【94】Binary Tree Inorder Traversal node
【95】Unique Binary Search Trees II (2018年11月14日,算法羣)git
給了一個 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 };
這題還能用 dp 解答,估計能快點。dp怎麼解答看discuss。app
【96】Unique Binary Search Trees (2018年11月14日,算法羣相關題複習)ide
給了一個 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) post
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 };
【98】Validate Binary Search Tree ui
寫個函數檢查一棵樹是否是BSTthis
題解:直接判斷左兒子比根小,右兒子比跟大是會WA的... 舉個會WA的例子。
【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 };
【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
【107】Binary Tree Level Order Traversal II
【108】Convert Sorted Array to Binary Search Tree
給一個增序的vector, 創建一棵高度平衡的BST.
這個題一開始懵了,不會作。。。信不信考到你就掛了orz
思路是二分的思想,從root開始建樹,而後左兒子,右兒子。
【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 };
【111】Minimum Depth of Binary Tree
【112】Path Sum
【113】Path Sum II
【114】Flatten Binary Tree to Linked List
把一顆二叉樹拍平成一個鏈表。如圖。判空,莫忘。要取一個節點的子節點以前,要判斷這個節點是否爲空。
【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 };
【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
【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 };
【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 };
還有一種遞歸的方法能夠作。前提是 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 };
【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 };
【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 };
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 };
【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 };
【449】Serialize and Deserialize BST
【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 };
【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 };
本題我估計還有別的解法,給了 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 };
【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 };
【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 };
【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 };
本題有個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 };
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 };
【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 };
【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:
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 };
【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 };
【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 };
【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 };
【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 };