Skip to content

Commit

Permalink
Tree & 20230506 daily chanllenge
Browse files Browse the repository at this point in the history
  • Loading branch information
nldxtd committed May 6, 2023
1 parent 67d6dde commit 8923076
Show file tree
Hide file tree
Showing 14 changed files with 674 additions and 0 deletions.
29 changes: 29 additions & 0 deletions Tree/104.maximum-depth-of-binary-tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* @lc app=leetcode id=104 lang=cpp
*
* [104] Maximum Depth of Binary Tree
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL) return 0;
int lh=maxDepth(root->left);
int rh=maxDepth(root->right);
return 1+max(lh,rh);
}
};
// @lc code=end

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* @lc app=leetcode id=105 lang=cpp
*
* [105] Construct Binary Tree from Preorder and Inorder Traversal
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
unordered_map<int, int> valToIndex;
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for (int i = 0; i < inorder.size(); i++) {
valToIndex[inorder[i]] = i;
}
return build(preorder, 0, preorder.size() - 1,
inorder, 0, inorder.size() - 1);
}

TreeNode* build(vector<int>& preorder, int preStart, int preEnd,
vector<int>& inorder, int inStart, int inEnd) {
if (preStart > preEnd) {
return nullptr;
}

// root 节点对应的值就是前序遍历数组的第一个元素
int rootVal = preorder[preStart];
// rootVal 在中序遍历数组中的索引
int index = valToIndex[rootVal];

int leftSize = index - inStart;

// 先构造出当前根节点
TreeNode* root = new TreeNode(rootVal);
// 递归构造左右子树
root->left = build(preorder, preStart + 1, preStart + leftSize,
inorder, inStart, index - 1);

root->right = build(preorder, preStart + leftSize + 1, preEnd,
inorder, index + 1, inEnd);
return root;
}
};
// @lc code=end

47 changes: 47 additions & 0 deletions Tree/114.flatten-binary-tree-to-linked-list.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* @lc app=leetcode id=114 lang=cpp
*
* [114] Flatten Binary Tree to Linked List
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
// base case
if (root == nullptr) return;

// 利用定义,把左右子树拉平
flatten(root->left);
flatten(root->right);

/**** 后序遍历位置 ****/
// 1、左右子树已经被拉平成一条链表
TreeNode* left = root->left;
TreeNode* right = root->right;

// 2、将左子树作为右子树
root->left = nullptr;
root->right = left;

// 3、将原先的右子树接到当前右子树的末端
TreeNode* p = root;
while (p->right != nullptr) {
p = p->right;
}
p->right = right;
}
};
// @lc code=end

52 changes: 52 additions & 0 deletions Tree/116.populating-next-right-pointers-in-each-node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* @lc app=leetcode id=116 lang=cpp
*
* [116] Populating Next Right Pointers in Each Node
*/

// @lc code=start
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
Node* connect(Node* root) {
if (root == nullptr) return nullptr;
// 遍历「三叉树」,连接相邻节点
traverse(root->left, root->right);
return root;
}

// 三叉树遍历框架
void traverse(Node* node1, Node* node2) {
if (node1 == nullptr || node2 == nullptr) {
return;
}
/**** 前序位置 ****/
// 将传入的两个节点穿起来
node1->next = node2;

// 连接相同父节点的两个子节点
traverse(node1->left, node1->right);
traverse(node2->left, node2->right);
// 连接跨越父节点的两个子节点
traverse(node1->right, node2->left);
}
};
// @lc code=end

32 changes: 32 additions & 0 deletions Tree/144.binary-tree-preorder-traversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* @lc app=leetcode id=144 lang=cpp
*
* [144] Binary Tree Preorder Traversal
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
vector<int> ans;
public:
vector<int> preorderTraversal(TreeNode* root) {
if (root) {
ans.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
return ans;
}
};
// @lc code=end

38 changes: 38 additions & 0 deletions Tree/226.invert-binary-tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* @lc app=leetcode id=226 lang=cpp
*
* [226] Invert Binary Tree
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
// 利用函数定义,先翻转左右子树
TreeNode* left = invertTree(root->left);
TreeNode* right = invertTree(root->right);

// 然后交换左右子节点
root->left = right;
root->right = left;

// 和定义逻辑自恰:以 root 为根的这棵二叉树已经被翻转,返回 root
return root;
}
};
// @lc code=end

59 changes: 59 additions & 0 deletions Tree/297.serialize-and-deserialize-binary-tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* @lc app=leetcode id=297 lang=cpp
*
* [297] Serialize and Deserialize Binary Tree
*/

// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:

string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
}

TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}

private:

void serialize(TreeNode* root, ostringstream& out) {
if (root) {
out << root->val << ' ';
serialize(root->left, out);
serialize(root->right, out);
} else {
out << "# ";
}
}

TreeNode* deserialize(istringstream& in) {
string val;
in >> val;
if (val == "#")
return nullptr;
TreeNode* root = new TreeNode(stoi(val));
root->left = deserialize(in);
root->right = deserialize(in);
return root;
}
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
// @lc code=end

80 changes: 80 additions & 0 deletions Tree/315.count-of-smaller-numbers-after-self.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* @lc app=leetcode id=315 lang=cpp
*
* [315] Count of Smaller Numbers After Self
*/

// @lc code=start
class Solution {
public:
struct Pair {
int val, id;
Pair(int val, int id) {
// 记录数组的元素值
this->val = val;
// 记录元素在数组中的原始索引
this->id = id;
}
};

// 归并排序所用的辅助数组
Pair* temp;
// 记录每个元素后面比自己小的元素个数
int* count;

// 主函数
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
count = new int[n]();
temp = new Pair[n]();
Pair* arr = new Pair[n];
// 记录元素原始的索引位置,以便在 count 数组中更新结果
for (int i = 0; i < n; i++)
arr[i] = Pair(nums[i], i);

// 执行归并排序,本题结果被记录在 count 数组中
sort(arr, 0, n - 1);

vector<int> res;
for (int i = 0; i < n; i++)
res.push_back(count[i]);
delete[] count;
delete[] temp;
return res;
}

// 归并排序
void sort(Pair* arr, int lo, int hi) {
if (lo == hi) return;
int mid = lo + (hi - lo) / 2;
sort(arr, lo, mid);
sort(arr, mid + 1, hi);
merge(arr, lo, mid, hi);
}

// 合并两个有序数组
void merge(Pair* arr, int lo, int mid, int hi) {
for (int i = lo; i <= hi; i++) {
temp[i] = arr[i];
}

int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
arr[p] = temp[j++];
} else if (j == hi + 1) {
arr[p] = temp[i++];
// 更新 count 数组
count[arr[p].id] += j - mid - 1;
} else if (temp[i].val > temp[j].val) {
arr[p] = temp[j++];
} else {
arr[p] = temp[i++];
// 更新 count 数组
count[arr[p].id] += j - mid - 1;
}
}
}
};
// @lc code=end

Loading

0 comments on commit 8923076

Please sign in to comment.