【LeetCode】树(共94题)

【94】Binary Tree Inorder Traversal (2021年7月10日,review)

二叉树中序遍历。

写法1: 递归 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 // time complexity: O(n)
13 // space complexity: O(n)
14 class Solution {
15 public:
16     vector<int> inorderTraversal(TreeNode* root) {
17         vector<int> ans;
18         inorderHelper(root, ans);
19         return ans;
20     }
21     void inorderHelper(TreeNode* root, vector<int>& ans) {
22         if (!root) {
23             return;
24         }
25         inorderHelper(root->left, ans);
26         ans.push_back(root->val);
27         inorderHelper(root->right, ans);
28     }
29 };
View Code

 

【95】Unique Binary Search Trees II (2018年11月14日,算法群)

给了一个 n,返回结点是 1 ~ n 的所有形态的BST。

题解:枚举每个根节点 r, 然后递归的生成左右子树的所有集合,然后做笛卡尔积。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<TreeNode*> generateTrees(int n) {
13         if (n == 0) {return vector<TreeNode*>();}
14         return generateTrees(1, n);
15     }
16     
17     vector<TreeNode*> generateTrees(int begin, int end) {
18         vector<TreeNode*> ret;
19         if (begin > end) {
20             ret.push_back(nullptr);
21             return ret;
22         }
23         if (begin == end) {
24             TreeNode* root = new TreeNode(begin);
25             ret.push_back(root);
26             return ret;
27         }
28         for (int r = begin; r <= end; ++r) {
29             vector<TreeNode*> leftSon = generateTrees(begin, r - 1);
30             vector<TreeNode*> rightSon = generateTrees(r + 1, end);
31             for (auto leftEle : leftSon) {
32                 for (auto rightEle : rightSon) {
33                     TreeNode* root = new TreeNode(r);
34                     root->left = leftEle;
35                     root->right = rightEle;
36                     ret.push_back(root);
37                 }
38             }
39         }
40         return ret;
41     }
42 };
View Code

这题还能用 dp 解答,估计能快点。dp怎么解答看discuss。

 

【96】Unique Binary Search Trees (2018年11月14日,算法群相关题复习)

给了一个 n, 返回结点是 1 ~ n 的 BST 有多少种形态。

题解:dp, dp[k] 代表 k 个结点的 BST 有多少种形态。dp[0] = 1, dp[1] =1, dp[2] = 2。dp[k] = sigma(dp[left] * dp[k - left - 1]) (0 <= left < k) 

 1 class Solution {
 2 public:
 3     int numTrees(int n) {
 4         // f[0] = 1, f[1] = 1, f[2] = 2, 
 5         // f[k] = sigma(f[i] * f[k-i-1]) (i belongs [0, k-1])
 6         vector<int> dp(n+1, 0);
 7         dp[0] = dp[1] = 1; dp[2] = 2;
 8         for (int k = 3; k <= n; ++k) {
 9             for (int left = 0; left <= k-1; ++left) {
10                 int right = k - left - 1;
11                 dp[k] += dp[left] * dp[right];
12             }
13         }
14         return dp[n];
15     }
16 };
View Code

 

【98】Validate Binary Search Tree 

写个函数检查一棵树是不是BST

题解:直接判断左儿子比根小,右儿子比跟大是会WA的... 举个会WA的例子。

 

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {
13 public:
14     bool isValidBST(TreeNode* root) {
15         // lowerBound 和 upperBound 一开始都是 nullptr,表示不 check 边界,可以无限大或者无限小
16         return validate(root, nullptr, nullptr);
17     }
18     bool validate(TreeNode* root, TreeNode* lowerBound, TreeNode* upperBound) {
19         if (!root) {return true;}
20         if (lowerBound && lowerBound->val >= root->val 
21             || upperBound && upperBound->val <= root->val) {
22             return false;
23         }
24         return validate(root->left, lowerBound, root) && validate(root->right, root, upperBound);
25     }
26 };
View Code

 

 

【99】Recover Binary Search Tree 

【100】Same Tree

【101】Symmetric Tree 

 

【102】Binary Tree Level Order Traversal  (2019年1月26日,谷歌tag复习)

二叉树的层级遍历

题解:bfs,这题不上代码。

 

【103】Binary Tree Zigzag Level Order Traversal (2019年1月26日,谷歌tag复习)

二叉树的层级遍历,zigzag版本

题解:用两个栈,不是用队列了。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
13         if (!root) {
14             return vector<vector<int>>();
15         }
16         stack<TreeNode*> stk, stk2;
17         stk.push(root);
18         vector<vector<int>> ret;
19         int line = 0;
20         while (!stk.empty()) {  //stk: [7, 15]
21             const int size = stk.size(); // size = 2
22             vector<int> rows;
23             for (int i = 0; i < size; ++i) {
24                 TreeNode* cur = stk.top(); stk.pop(); //cur = 15, 7
25                 rows.push_back(cur->val); //rows = {15}
26                 if (line & 1) { // 
27                     if (cur->right) {
28                         stk2.push(cur->right); //stk2 : 7 
29                     }
30                     if (cur->left) {
31                         stk2.push(cur->left); //stk2 : 7, 15
32                     }
33                 } else {
34                     if (cur->left) {
35                         stk2.push(cur->left);  
36                     }
37                     if (cur->right) {
38                         stk2.push(cur->right); 
39                     }
40                 }
41             }
42             ret.push_back(rows);  //[[3], [20, 9], ]
43             line ^= 1; //line = 0;
44             swap(stk, stk2); // stk = [7, 15]
45         }
46         return ret;
47     }
48 };
View Code

 

【104】Maximum Depth of Binary Tree 

【105】Construct Binary Tree from Preorder and Inorder Traversal 

【106】Construct Binary Tree from Inorder and Postorder Traversal 

给中序遍历 和 后序遍历, 重建二叉树。

题解:没啥难度,一次ac

View Code

 

【107】Binary Tree Level Order Traversal II

【108】Convert Sorted Array to Binary Search Tree 

给一个增序的vector, 建立一棵高度平衡的BST.

这个题一开始懵了,不会做。。。信不信考到你就挂了orz

思路是二分的思想,从root开始建树,然后左儿子,右儿子。

View Code

 

【110】Balanced Binary Tree  (2019年1月26日,谷歌tag复习)

判断一棵树是不是高度平衡的二叉树。

题解:分别判断左儿子和右儿子是不是高度平衡的二叉树。然后判断左儿子的高度和右儿子的高度是否相差小于等于1.

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool isBalanced(TreeNode* root) {
13         if (!root) {return true;}
14         int leftHeight = getHeight(root->left), rightHeight = getHeight(root->right);
15         if (abs(leftHeight - rightHeight) > 1) {
16             return false;
17         }
18         return isBalanced(root->left) && isBalanced(root->right);
19     }
20     int getHeight(TreeNode* root) {
21         if (!root) { return 0;}
22         if (!root->left && !root->right) {return 1;}
23         return max(getHeight(root->left), getHeight(root->right)) + 1;
24     }
25 };
View Code

 

【111】Minimum Depth of Binary Tree 

【112】Path Sum 

【113】Path Sum II 

【114】Flatten Binary Tree to Linked List 

把一颗二叉树拍平成一个链表。如图。判空,莫忘。要取一个节点的子节点之前,要判断这个节点是否为空。

View Code

 

【116】Populating Next Right Pointers in Each Node (2019年1月26日,谷歌tag复习)

给了一个很特殊的满二叉树的结构,让我们把每层的节点都和它的兄弟/邻居节点连接起来。

题解:我是用了 bfs 来解决这个问题的。

 1 /**
 2  * Definition for binary tree with next pointer.
 3  * struct TreeLinkNode {
 4  *  int val;
 5  *  TreeLinkNode *left, *right, *next;
 6  *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     void connect(TreeLinkNode *root) {
12         if (!root) { return; }
13         queue<TreeLinkNode* > que;
14         que.push(root);
15         while (!que.empty()) {
16             const int size = que.size();
17             for (int i = 0; i < size; ++i) {
18                 TreeLinkNode* cur = que.front(); que.pop();
19                 if (i == size - 1) {
20                     cur->next = nullptr;
21                 } else {
22                     cur->next = que.front();
23                 }
24                 if (cur->left) {
25                     que.push(cur->left);
26                 }
27                 if (cur->right) {
28                     que.push(cur->right);
29                 }
30             }
31         }
32         return;
33     }
34 };
View Code

 

【117】Populating Next Right Pointers in Each Node II (2019年1月26日,谷歌tag复习)

本题和116的区别在于,给的树可能不是满二叉树。

题解:还是116的方法可以解。代码同116,一行都不用改。

 

【124】Binary Tree Maximum Path Sum 

【129】Sum Root to Leaf Numbers 

【144】Binary Tree Preorder Traversal 

【145】Binary Tree Postorder Traversal 

【156】Binary Tree Upside Down 

【173】Binary Search Tree Iterator 

【199】Binary Tree Right Side View 

 

【222】Count Complete Tree Nodes (2021-10-24)

数一个完全二叉树的节点个数。

https://leetcode.com/problems/count-complete-tree-nodes/

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {
13 public:
14     int countNodes(TreeNode* root) {
15         if (!root) {
16             return 0;
17         }
18         return countNodes(root->left) + countNodes(root->right) + 1;
19     }
20 };
View Code

 

【226】Invert Binary Tree 

 

【230】Kth Smallest Element in a BST 

 

【235】Lowest Common Ancestor of a Binary Search Tree (2019年1月29日,复习)

返回一棵 bst 的给定两个结点的最小公共祖先。

题解:如果这两个结点的值一个小于等于root,一个大于等于root,那么返回root。否则如果都比root小的话,就递归到左边结点,如果都比root大的话,就递归到右边结点。 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
13         if (!root || !p || !q) {return nullptr;}
14         if (p->val <= root->val && q->val >= root->val || q->val <= root->val && p->val >= root->val) {
15             return root;
16         }
17         if (p->val < root->val && q->val < root->val) {
18             return lowestCommonAncestor(root->left, p, q);
19         }
20         return lowestCommonAncestor(root->right, p, q);
21     }
22 };
View Code

 

【236】Lowest Common Ancestor of a Binary Tree (2019年1月29日,复习)

给定一棵任意二叉树和两个结点p,q,返回p,q的最小公共祖先。

题解:比较简单想的一种解法就是从root开始分别做两个dfs,找 p 和 q 的路径,找到之后,返回公共的最后一个结点。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
13         if (!root) {return root;}
14         vector<TreeNode*> pathP, pathQ;
15         dfs(root, p, pathP);
16         dfs(root, q, pathQ);
17         reverse(pathP.begin(), pathP.end());
18         reverse(pathQ.begin(), pathQ.end());
19         TreeNode* res = root;
20         for (int i = 0; i < (int)min(pathP.size(), pathQ.size()); ++i) {
21             if (pathP[i] == pathQ[i]) {
22                 res = pathP[i];
23             } else {
24                 break;
25             }
26         }
27         return res;
28     }
29     bool dfs(TreeNode* root, TreeNode* p, vector<TreeNode*>& path) {
30         if (!root) { return false; }
31         if (root == p || dfs(root->left, p, path) || dfs(root->right, p, path)) {
32             path.push_back(root);
33             return true;
34         }
35         return false;
36     }
37 };
View Code

还有一种递归的方法可以做。前提是 p, q这两个结点要保证在二叉树里面。

1. 如果当前node为空,或者等于p,q中的任意一个的话,那么就返回node。

2.分别递归调用node的左右子树,查看返回结果,如果leftRes == null ,就说明两个结点都在右子树里面,返回rightRes,如果rightRes == null, 说明两个结点都在左子树里面,返回leftRes。否则的话,一左一右说明应该返回当前层的node。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
13         if (!root) {return root;}
14         if (root == p || root == q) {
15             return root;
16         }
17         TreeNode* leftRes = lowestCommonAncestor(root->left, p, q);
18         TreeNode* rightRes = lowestCommonAncestor(root->right, p, q);
19         if (!leftRes) {
20             return rightRes;
21         }
22         if (!rightRes) {
23             return leftRes;
24         }
25         return root;
26     }
27 };
View Code

 

【250】Count Univalue Subtrees 

返回一棵二叉树所有结点值都相同的子树的个数。

题解:叶子结点肯定是 univalue 的子树,如果不是叶子结点,就先判断它的左右儿子是不是 univalue subtree,如果是,在判断根节点和左右儿子结点这三个值是否相等,如果子树都不是 univalue 的了,那么包含根结点的更加不是了。

不要随便在leetcode里面用静态变量,不然一个新的case如果没有重新初始化静态变量就直接在原来case的基础上累加/变化了。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 //如果是叶子结点,就直接+1, 如果不是叶子结点,就判断左右子树是不是uni-value tree,如果是,再判断root和左右儿子的值是否相等,不然如果子树不是 uni-val tree, 那么更大的树也肯定不是 uni-val tree。
11 class Solution {
12 public:
13     int countUnivalSubtrees(TreeNode* root) {
14         isSameVal(root);
15         return cnt;
16     }
17     bool isSameVal(TreeNode* root) {
18         if (!root) {return true;}
19         if (!root->left && !root->right) {
20             cnt++;
21             return true;
22         }
23         bool leftSame = isSameVal(root->left), rightSame = isSameVal(root->right);
24         if (!leftSame || !rightSame) {
25             return false;
26         }
27         if (!root->left && root->right && root->right->val == root->val) {
28             cnt++;
29             return true;
30         } else if (!root->right && root->left && root->left->val == root->val) {
31             cnt++;
32             return true;
33         } else if (root->left && root->right) {
34             if (root->val == root->left->val && root->val == root->right->val) {
35                 cnt++;
36                 return true;
37             }
38         }
39         return false;
40     }
41     int cnt = 0;
42 };
View Code

 

【255】Verify Preorder Sequence in Binary Search Tree 

【257】Binary Tree Paths 

【270】Closest Binary Search Tree Value 

【272】Closest Binary Search Tree Value II 

【285】Inorder Successor in BST 

【297】Serialize and Deserialize Binary Tree 

【298】Binary Tree Longest Consecutive Sequence 

【333】Largest BST Subtree 

【337】House Robber III (谷歌tag,2019年2月9日)

其实老实说我没怎么搞懂?===!!!

【366】Find Leaves of Binary Tree 

返回一棵二叉树所有叶子,直到这棵树为空。

题解:我是用 dfs 每次都遍历树的一层叶子,这层搞完之后就把它爹的指向叶子的指针给干掉。时间复杂度起码O(L*2^H) (L是层数,H是整棵树的高度)

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<vector<int>> findLeaves(TreeNode* root) {
13         vector<vector<int>> ans;
14         if (!root) {return ans;}
15         vector<int> temp;
16         while (!dfs(root, temp)) {
17             ans.push_back(temp);
18             temp.clear();
19         }
20         ans.push_back(temp);
21         return ans;
22     }
23     
24     bool dfs(TreeNode* root, vector<int>& temp) {
25         if (!root) {return false;}
26         if (!root->left && !root->right) {
27             temp.push_back(root->val);
28             return true;
29         }
30         bool l = dfs(root->left, temp), r = dfs(root->right, temp);
31         if (l) {
32             root->left = NULL;
33         } 
34         if (r) {
35             root->right = NULL;
36         }
37         return false;
38     }
39     
40 };
View Code

PS:这题可能有更加优秀的方法,看我这种遍历了L次根节点的肯定不够优秀。

 

【404】Sum of Left Leaves (2019年1月29日,easy)

返回一棵二叉树的所有左叶子结点的和。

题解:dfs,分类,分成左儿子,右儿子和根结点。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int sumOfLeftLeaves(TreeNode* root) {
13         return dfs(root, 0);
14     }
15     int dfs(TreeNode* root, int type) {//type: 0 当前结点是根结点, 1 当前结点是父亲结点的左儿子, 2 当前结点是父亲结点的右儿子
16         int ret = 0;
17         if (!root) {return ret;}
18         if (root->left) {
19             ret += dfs(root->left, 1);
20         }
21         if (root->right) {
22             ret += dfs(root->right, 2);
23         }
24         if (!root->left && !root->right && type == 1) {
25             ret += root->val;
26         }
27         return ret;
28     }
29 };
View Code

 

【426】Convert Binary Search Tree to Sorted Doubly Linked List 

【428】Serialize and Deserialize N-ary Tree 

【429】N-ary Tree Level Order Traversal 

【431】Encode N-ary Tree to Binary Tree 

 

【437】Path Sum III (2019年2月11日)

本题是 112,113 的进阶版本。给了一棵二叉树,和一个值 sum,返回树上有多少条路径的和等于 sum,路径的开始和结束不要求是根结点和叶子结点。

题解:利用一个辅助数组标记当前这条path的前缀和。当前结点的前缀和 - 前面某个结点的前缀和 == sum, res++

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int pathSum(TreeNode* root, int sum) {
13         if (!root) {return 0;}
14         vector<int> path{0};
15         dfs(root, path, sum);
16         return res;
17     }
18     int res = 0;
19     void dfs(TreeNode* root, vector<int>& path, const int sum) {
20         if (!root) {return; }
21         int num = root->val;
22         if (!path.empty()) {num += path.back();}
23         for (auto val : path) {
24             if (num - val == sum) { res++; }
25         }
26         path.push_back(num);
27         dfs(root->left, path, sum);
28         dfs(root->right, path, sum);
29         path.pop_back();
30     }
31 };
View Code

 

【449】Serialize and Deserialize BST (2021-10-24)

https://leetcode.com/problems/serialize-and-deserialize-bst/

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Codec {
11 public:
12 
13     // Encodes a tree to a single string.
14     string serialize(TreeNode* root) {
15         vector<int> path;
16         preOrder(root, path);
17     
18         return serialize(path);
19     }
20     string serialize(vector<int>& path) {
21         string ans = "";
22         for (auto& num : path) {
23             ans += to_string(num) + " ";
24         }
25         if (!path.empty()) {
26             ans.pop_back();
27         }
28         return ans;
29     }
30     void preOrder(TreeNode* root, vector<int>& path) {
31         if (!root) {return;}
32         path.push_back(root->val);
33         preOrder(root->left, path);
34         preOrder(root->right, path);
35     }
36 
37     TreeNode* buildBST(vector<int>& preOrder, int start, int end) {
38         if (start == -1 || start >= end) {
39             return nullptr;
40         }
41         int rootVal = preOrder[start];
42         TreeNode* root = new TreeNode(rootVal);
43         int rightStart = -1;
44         for (int i = start+1; i < end; ++i) {
45             if (preOrder[i] > rootVal) {
46                 rightStart = i;
47                 break;
48             }
49         }
50         if (rightStart == -1) {
51             rightStart = end; 
52         }
53         root->left = buildBST(preOrder, start+1, rightStart);
54         root->right = buildBST(preOrder, rightStart, end);
55         return root;
56     }
57     
58     // Decodes your encoded data to tree.
59     TreeNode* deserialize(string data) {
60         vector<int> preOrder;
61         stringstream ss(data);
62         string strNum;
63         while (ss >> strNum) {
64             preOrder.push_back(stoi(strNum));
65         }
66         return buildBST(preOrder, 0, preOrder.size());
67     }
68 };
69 
70 // Your Codec object will be instantiated and called as such:
71 // Codec* ser = new Codec();
72 // Codec* deser = new Codec();
73 // string tree = ser->serialize(root);
74 // TreeNode* ans = deser->deserialize(tree);
75 // return ans;
View Code

 

【450】Delete Node in a BST (2019年2月16日)

删除BST的一个指定结点,结点的key作为输入。

题解:先递归找到这个结点,然后如果这个结点的左儿子,右儿子有一个为空结点的话, 那么把另外一个儿子提上来。如果没有左右儿子,那么就返回nullptr,如果两个儿子都有的话,那么找到左儿子的最大值,递归删除左儿子的最大值,然后把自己的值替换成左儿子的最大值。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* deleteNode(TreeNode* root, int key) {
13         if (!root) {return root;}
14         if (key < root->val) { 
15             root->left = deleteNode(root->left, key);
16             return root;
17         }
18         if (key > root->val) { 
19             root->right = deleteNode(root->right, key);
20             return root;
21         }
22         if (root->left && !root->right) {
23             return root->left;
24         } else if (!root->left && root->right) {
25             return root->right;
26         } else if (!root->left && !root->right) {
27             return nullptr;
28         }
29         int leftMax = findMax(root->left);
30         root->left = deleteNode(root->left, leftMax);
31         root->val = leftMax;
32         return root;
33     }
34     int findMax(TreeNode* root) {
35         if (!root) {return -1;}
36         int res = root->val;
37         if (root->right) {
38             res = findMax(root->right);
39         }
40         return res;
41     }
42 };
View Code

  

【501】Find Mode in Binary Search Tree (2018年11月24日,冲刺题量)

给了一个有重复结点的BST,返回出现频率最高的结点是值的数组。

题解:我直接 dfs 了一下BST,用 map 保存每个结点出现了多少次。暴力解法。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<int> findMode(TreeNode* root) {
13         dfs(root);
14         vector<int> ret;
15         for (auto ele : mp) {
16             if (ele.second == mostFreq) {
17                 ret.push_back(ele.first);
18             }
19         }
20         return ret;
21     }
22     void dfs(TreeNode* root) {
23         if (!root) {return;}
24         if (root->left) {
25             dfs(root->left);
26         }
27         mp[root->val]++;
28         mostFreq = max(mp[root->val], mostFreq);
29         if (root->right) {
30             dfs(root->right);
31         }
32         return;
33     }
34     map<int, int> mp;
35     int mostFreq = 0;
36 };
View Code

本题我估计还有别的解法,给了 BST 的性质完全没有用到。==。。

 

【508】Most Frequent Subtree Sum 

【513】Find Bottom Left Tree Value 

【515】Find Largest Value in Each Tree Row 

 

【536】Construct Binary Tree from String (2019年2月15日)

给了一个string,由数字,括号组成,重构二叉树。

Input: "4(2(3)(1))(6(5))"
Output: return the tree root node representing the following tree:

       4
     /   \
    2     6
   / \   / 
  3   1 5   

 题解:递归。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* str2tree(string s) {
13         if (s.empty()) {return nullptr;}
14         int left = 0, right = 0, num = 0;
15         string strLeft, strRight;
16         int preIdx = -1;
17         for (int i = 0; i < s.size(); ++i) {
18             if (left == 0 && right == 0 && isdigit(s[i])) {
19                 num = num * 10 + (s[i] - '0');
20                 preIdx = i;
21             } else if (s[i] == '(') {
22                 left++;
23             } else if (s[i] == ')') {
24                 right++;
25             }
26             if (left == right && left != 0) {
27                 strLeft = s.substr(preIdx + 1, i - preIdx);
28                 strRight = s.substr(i + 1);
29                 break;
30             }
31         }
32         if (s[0] == '-') {num = -num;}
33         TreeNode * root = new TreeNode(num);
34         if (!strLeft.empty()) {
35             root->left = str2tree(strLeft.substr(1, strLeft.size()-2));
36         }
37         if (!strRight.empty()) {
38             root->right = str2tree(strRight.substr(1, strRight.size()-2));
39         }
40         return root;
41     }
42 };
View Code

 

【538】Convert BST to Greater Tree (2018年11月14日,冲刺题量)

给了一棵 BST,把这棵树变成 greater tree。变换方法是把一个结点的值变成这个结点原来的值,加上所有比这个结点值大的结点的和。

题解:我们考虑这棵 BST 的最右边的叶子结点肯定还是原来的值。然后我们用一个 summ 记录比当前结点大的所有结点的和。然后 dfs 这棵树,顺序就是 right -> root -> left.

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     //right -> root -> left
13     TreeNode* convertBST(TreeNode* root) {
14         int summ = 0;
15         dfs(root, summ);
16         return root;
17     }
18     void dfs(TreeNode* root, int& summ) {
19         if (!root) { return; }
20         dfs(root->right, summ);
21         root->val += summ;
22         summ = root->val;
23         dfs(root->left, summ);
24         return;
25     }
26 };
View Code

  

【543】Diameter of Binary Tree (2018年11月14日,为了冲点题量)

给了一棵二叉树,问二叉树的直径多少。直径的定义是从一个结点到另外一个结点的最长距离。

题解:这个最长距离可能出现在哪里?一个结点的孩子结点作为根节点的子树的直径,或者这个结点自己做根的直径。(代码写的有点乱,但是还是过了orz)。(本题应该还有更快的方法,要看。 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int diameterOfBinaryTree(TreeNode* root) {
13         if (!root) {return 0;}
14         int leftres = diameterOfBinaryTree(root->left);
15         int rightres = diameterOfBinaryTree(root->right);
16         int tempres = max(leftres, rightres);
17         int selfres = getPathLen(root->left) + 1 + getPathLen(root->right) + 1;
18         tempres = max(selfres, tempres);
19         globalMax = max(tempres, globalMax);
20         return globalMax;
21     }
22     int getPathLen(TreeNode* root) {
23         if (!root) {return -1;}
24         if (pathLen.find(root) != pathLen.end()) {return pathLen[root];}
25         if (!root->left && !root->right) {
26             pathLen[root] == 0;
27             return 0;
28         }
29         pathLen[root] = max(getPathLen(root->left), getPathLen(root->right)) + 1;
30         return pathLen[root];
31     }
32     int globalMax = 0;
33     unordered_map<TreeNode*, int> pathLen;
34 };
View Code

 

【545】Boundary of Binary Tree 

【549】Binary Tree Longest Consecutive Sequence II 

【559】Maximum Depth of N-ary Tree 

【563】Binary Tree Tilt 

【572】Subtree of Another Tree 

【582】Kill Process 

【589】N-ary Tree Preorder Traversal (2018年11月14日,为了冲点题量)

给了一个 N叉树,返回它的先序遍历。

题解:直接dfs。

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     vector<Node*> children;
 7 
 8     Node() {}
 9 
10     Node(int _val, vector<Node*> _children) {
11         val = _val;
12         children = _children;
13     }
14 };
15 */
16 class Solution {
17 public:
18     vector<int> preorder(Node* root) {
19         vector<int> ret;
20         if (!root) {return ret;}
21         preorder(root, ret);
22         return ret;
23     }
24     void preorder(Node* root, vector<int>& ret) {
25         ret.push_back(root->val);
26         for (auto kid : root->children) {
27             preorder(kid, ret);
28         }
29         return;
30     }
31 
32 };
View Code

本题有个follow-up, 问能不能写个 iteratively 的代码。还没做。

 

【590】N-ary Tree Postorder Traversal (2018年11月14日,为了冲点题量)

给了一个 N 叉树,返回它的后序遍历。

题解:直接dfs。

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     vector<Node*> children;
 7 
 8     Node() {}
 9 
10     Node(int _val, vector<Node*> _children) {
11         val = _val;
12         children = _children;
13     }
14 };
15 */
16 class Solution {
17 public:
18     vector<int> postorder(Node* root) {
19         vector<int> ret;
20         if (!root) {return ret;}
21         postorder(root, ret);
22         return ret;
23     }
24     void postorder(Node* root, vector<int>& ret) {
25         if (!root) {return;}
26         for (auto kid : root->children) {
27             postorder(kid, ret);
28         }
29         ret.push_back(root->val);
30         return;
31     }
32 };
View Code

follow-up还是能不能写 iteratively 的代码,依旧还没看。

 

 

【606】Construct String from Binary Tree (2018年11月14日,为了冲点题量,这题以前还写错了,这次一次过了orz)

从给定的二叉树中形成一个字符串,返回字符串。省略不必要的括号,比如叶子结点下面的空结点。或者如果一个结点有左儿子,没有右儿子,那么他右儿子的括号可以省略,但是如果他有右儿子,没有左儿子,那么左儿子括号不能省略。 

Example 1:
Input: Binary tree: [1,2,3,4]
       1
     /   \
    2     3
   /    
  4     

Output: "1(2(4))(3)"
Explanation: Originallay it needs to be "1(2(4)())(3()())", 
but you need to omit all the unnecessary empty parenthesis pairs. 
And it will be "1(2(4))(3)".

Example 2:
Input: Binary tree: [1,2,3,null,4]
       1
     /   \
    2     3
     \  
      4 

Output: "1(2()(4))(3)"
Explanation: Almost the same as the first example, 
except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output.
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     string tree2str(TreeNode* t) {
13         if (!t) {return "";}
14         string strLeft = tree2str(t->left);
15         string strRight = tree2str(t->right);
16         string ret = "";
17         ret = to_string(t->val);
18         if (!strLeft.empty()) {
19             ret += "(" + strLeft + ")";
20         }
21         if(!strRight.empty()) {
22             if (strLeft.empty()) {
23                 ret += "()("  + strRight + ")";
24             } else {
25                 ret += "(" + strRight + ")";
26             }
27         }
28         return ret;
29     }
30 };
View Code

 

【617】Merge Two Binary Trees 

【623】Add One Row to Tree 

 

【637】Average of Levels in Binary Tree (2018年11月27日)

返回一棵二叉树每层的平均值。

Example 1:
Input:
    3
   / \
  9  20
    /  \
   15   7
Output: [3, 14.5, 11]
Explanation:
The average value of nodes on level 0 is 3,  on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].

题解:bfs,每层求和,然后求平均值。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<double> averageOfLevels(TreeNode* root) {
13         vector<double> ret;
14         if (!root) {return ret;}
15         queue<TreeNode*> que;
16         que.push(root);
17         while (!que.empty()) {
18             int size = que.size();
19             double summ = 0.0;
20             for (int i = 0; i < size; ++i) {
21                 TreeNode* cur = que.front(); que.pop();
22                 summ += cur->val;
23                 if (cur->left) {
24                     que.push(cur->left);
25                 }
26                 if (cur->right) {
27                     que.push(cur->right);
28                 }
29             }
30             ret.push_back(summ / size);
31             summ = 0.0;
32         }
33         return ret;
34     }
35 };
View Code

 

【652】Find Duplicate Subtrees 

【653】Two Sum IV - Input is a BST 

 

【654】Maximum Binary Tree (2018年11月27日)

Given an integer array with no duplicates. A maximum tree building on this array is defined as follow:

  1. The root is the maximum number in the array.
  2. The left subtree is the maximum tree constructed from left part subarray divided by the maximum number.
  3. The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. 

Construct the maximum tree by the given array and output the root node of this tree.

Input: [3,2,1,6,0,5]
Output: return the tree root node representing the following tree:

      6
    /   \
   3     5
    \    / 
     2  0   
       \
        1

题解:递归求解

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
13         const int n = nums.size();
14         if (n == 0) {return nullptr;}
15         int maxValue = nums[0], maxIdx = 0;
16         for (int i = 1; i < n; ++i) {
17             if (nums[i] > maxValue) {
18                 maxIdx = i;
19                 maxValue = nums[i];
20             }
21         }
22         TreeNode* root = new TreeNode(maxValue);
23         vector<int> LeftSon(nums.begin(), nums.begin()+maxIdx);
24         vector<int> RightSon(nums.begin() + maxIdx + 1, nums.end());
25         root->left = constructMaximumBinaryTree(LeftSon);
26         root->right = constructMaximumBinaryTree(RightSon);
27         return root;
28     }
29 };
View Code

 

【655】Print Binary Tree 

【662】Maximum Width of Binary Tree 

【663】Equal Tree Partition 

【666】Path Sum IV

 

【669】Trim a Binary Search Tree (2019年2月12日)

给了一棵BST,和一个闭区间[L, R], 要 trim 这颗树,返回只在给定区间内的结点的BST。

题解:递归。

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* trimBST(TreeNode* root, int L, int R) {
13         if (!root) {return root;}
14         if (R < root->val) { return trimBST(root->left, L, R); }
15         if (L > root->val) { return trimBST(root->right, L, R); }
16         root->left = trimBST(root->left, L, R);
17         root->right = trimBST(root->right, L, R);
18         return root;
19     }
20 };
View Code

 

 

【671】Second Minimum Node In a Binary Tree 

【684】Redundant Connection 

【685】Redundant Connection II 

【687】Longest Univalue Path 

【700】Search in a Binary Search Tree 

 

【701】Insert into a Binary Search Tree (2018年11月25日)

给一棵 BST 里面插入一个值为 val 的结点。

题解:直接递归插入。 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* insertIntoBST(TreeNode* root, int val) {
13         if (!root) {
14             root = new TreeNode(val);
15             return root;
16         }   
17         if (root->val > val) {
18             if (root->left) {
19                 root->left = insertIntoBST(root->left, val);
20             } else {
21                 root->left = new TreeNode(val);
22             }
23         } else if (root->val < val) {
24             if (root->right) {
25                 root->right = insertIntoBST(root->right, val);
26             } else {
27                 root->right = new TreeNode(val);
28             }
29         }
30         return root;
31     }
32 };
View Code

 

【742】Closest Leaf in a Binary Tree 

 

【814】Binary Tree Pruning (2018年11月27日)

给一棵二叉树剪枝,把全 0 的子树全部减没。返回新的根节点。

题解:直接递归做吧,第一次提交 WA 了一次。因为没考虑清楚先递归处理子树,还是先处理本身。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* pruneTree(TreeNode* root) {
13         if (!root) {return root;}
14         if (root->left) {
15             root->left = pruneTree(root->left);
16             TreeNode* node = root->left;
17             if (!node->left && !node->right && node->val == 0) {
18                 root->left = nullptr;
19             }
20         }
21         if (root->right) {
22             root->right = pruneTree(root->right);
23             TreeNode* node = root->right;
24             if (!node->left && !node->right && node->val == 0) {
25                 root->right = nullptr;
26             }
27         }
28         return root;
29     }
30 };
View Code

 

【834】Sum of Distances in Tree 

【863】All Nodes Distance K in Binary Tree 

【865】Smallest Subtree with all the Deepest Nodes 

【872】Leaf-Similar Trees 

【889】Construct Binary Tree from Preorder and Postorder Traversal 

【894】All Possible Full Binary Trees 

 

【897】Increasing Order Search Tree (2019年2月10日,算法群打卡)

给了一棵BST,重新排布树上的结点,使得树上最左边的叶子结点是它的根,然后树上的每个结点都没有左子树,只有一个右儿子。

题解:我们的目标是 res = inorder(root.left) + root + inorder(root.right),所以递归就行了,传入一个tail指针。注意这个题不能重新搞一棵树出来,需要rearrange。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* increasingBST(TreeNode* root, TreeNode* tail = nullptr) {
13         if (!root) {return tail;}
14         TreeNode* ret = increasingBST(root->left, root);
15         root->left = nullptr;
16         root->right = increasingBST(root->right, tail);
17         return ret;
18     }
19 };
View Code

 

 

 

 

posted @ 2019-02-16 17:31  zhangwanying  阅读(580)  评论(0编辑  收藏  举报