一刷leetcode——树
94. Binary Tree Inorder Traversal
题意:中序遍历二叉树
我的思路:递归水题
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void dfs(TreeNode* root, vector<int> &ans) { if (root->left) dfs(root->left, ans); ans.push_back(root->val); if (root->right) dfs(root->right, ans); } vector<int> inorderTraversal(TreeNode* root) { vector<int> ans; if (root) dfs(root, ans); return ans; } };
九章最优解:一样
class Solution { /** * @param root: The root of binary tree. * @return: Inorder in vector which contains node values. */ public: vector<int> inorder; void traverse(TreeNode *root) { if (root == NULL) { return; } traverse(root->left); inorder.push_back(root->val); traverse(root->right); } vector<int> inorderTraversal(TreeNode *root) { inorder.clear(); traverse(root); return inorder; // write your code here } };
95. Unique Binary Search Trees II
题意:输出1~n构成的所有二叉树
我的思路:dfs
我的代码:
class Solution { public: vector<TreeNode*> dfs(int f, int t) { vector<TreeNode*> ret; if (f == t) { TreeNode* tmp = new TreeNode(f); ret.push_back(tmp); } else if (f < t) { for (int i = f; i <= t; i++) { vector<TreeNode*> l = dfs(f, i-1), r = dfs(i+1, t); for (int j = 0; j < l.size(); j++) for (int k = 0; k < r.size(); k++) { TreeNode* tmp = new TreeNode(i); tmp->left = l[j]; tmp->right = r[k]; ret.push_back(tmp); } } } else { ret.push_back(NULL); } return ret; } vector<TreeNode*> generateTrees(int n) { if (n == 0) { vector<TreeNode*> ret; return ret; } return dfs(1, n); } };
98. Validate Binary Search Tree
题意:检验是否是正确的二叉搜索树
我的思路:dfs中序遍历
我的代码:
class Solution { public: TreeNode* pre; void dfs(TreeNode* root, int &ans) { if (root->left) dfs(root->left, ans); if (pre && root->val <= pre->val) { ans = 0; return; } pre = root; if (root->right) dfs(root->right, ans); } bool isValidBST(TreeNode* root) { int ans = 1; if (root) dfs(root, ans); return ans; } };
99. Recover Binary Search Tree
题意:给定二叉搜索树中有两个节点错位,将他们复位
我的思路:二叉搜索树中序遍历应当是递增序列,根据这一性质即可找出错位的节点
我的代码:
class Solution { public: TreeNode* pre, *p1, *p2; void dfs(TreeNode* root) { //中序遍历 if (root->left) dfs(root->left); if (pre && pre->val > root->val) { if (p1 == NULL) { p1 = pre; p2 = root; } else p2 = root; } pre = root; if (root->right) dfs(root->right); } void recoverTree(TreeNode* root) { if (root) { dfs(root); swap(p1->val, p2->val); } return; } };
101. Symmetric Tree
题意:判断一棵二叉树是否镜像
我的思路:递归解法,bugfree
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool dfs(TreeNode* l, TreeNode* r) { if (l->val != r->val) return 0; if (l->left == NULL && l->right == NULL && r->left == NULL && r->right == NULL) return 1; if (l->left == NULL && r->right == NULL && r->left != NULL && l->right != NULL) return dfs(l->right, r->left); if (r->left == NULL && l->right == NULL && l->left != NULL && r->right != NULL) return dfs(l->left, r->right); if (r->left != NULL && l->right != NULL && l->left != NULL && r->right != NULL) return dfs(l->left, r->right) && dfs(l->right, r->left); return 0; } bool isSymmetric(TreeNode* root) { if (root == NULL) return 1; if (root->left == NULL && root->right == NULL) return 1; if (root->left == NULL || root->right == NULL) return 0; return dfs(root->left, root->right); } };
102. Binary Tree Level Order Traversal
题意:将树分层形成一个vector<vector<int>>,每层从左到右
我的思路:记录层dfs,bugfree
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void dfs(TreeNode* root, vector<vector<int>> &ans, int i) { if (root == NULL) return; if (ans.size() <= i) { vector<int> tmp; ans.push_back(tmp); } ans[i].push_back(root->val); if (root->left) dfs(root->left, ans, i+1); if (root->right) dfs(root->right, ans, i+1); } vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> ans; dfs(root, ans, 0); return ans; } };
九章最优解:BFS
public: vector<vector<int>> levelOrder(TreeNode *root) { vector<vector<int>> result; if (root == NULL) { return result; } queue<TreeNode *> Q; Q.push(root); while (!Q.empty()) { int size = Q.size(); vector<int> level; for (int i = 0; i < size; i++) { TreeNode *head = Q.front(); Q.pop(); level.push_back(head->val); if (head->left != NULL) { Q.push(head->left); } if (head->right != NULL) { Q.push(head->right); } } result.push_back(level); } return result; } };
107. Binary Tree Level Order Traversal II
题意:将树分层输出,下层先出
我的思路:把上题的结果倒置输出
我的代码:
class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>> result; if (root == NULL) { return result; } queue<TreeNode *> Q; Q.push(root); while (!Q.empty()) { int size = Q.size(); vector<int> level; for (int i = 0; i < size; i++) { TreeNode *head = Q.front(); Q.pop(); level.push_back(head->val); if (head->left != NULL) { Q.push(head->left); } if (head->right != NULL) { Q.push(head->right); } } result.push_back(level); } reverse(result.begin(), result.end()); return result; } };
九章最优解:一样
103. Binary Tree Zigzag Level Order Traversal
题意:将一棵二叉树从上到下之字形输出
我的思路:bfs+栈,两个栈轮着用,一层从左往右进,一层从右往左进
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> result; if (root == NULL) return result; stack<TreeNode *> s[2]; bool flag = 1; s[flag].push(root); while (!s[flag].empty()) { vector<int> tmp; int t = flag^1, n = s[flag].size(); for (int i = 0; i < n; i++) { TreeNode *head = s[flag].top(); s[flag].pop(); tmp.push_back(head->val); if (flag) { if (head->left != NULL) s[t].push(head->left); if (head->right != NULL) s[t].push(head->right); } else { if (head->right != NULL) s[t].push(head->right); if (head->left != NULL) s[t].push(head->left); } } result.push_back(tmp); flag = flag^1; } return result; } };
九章最优解:开一个结构体node记录层数,该翻转翻转
struct Node { TreeNode *node; int level; Node(){} Node(TreeNode *n, int l):node(n), level(l){} }; class Solution { /** * @param root: The root of binary tree. * @return: A list of lists of integer include * the zigzag level order traversal of its nodes' values */ public: vector<vector<int>> zigzagLevelOrder(TreeNode *root) { // write your code here vector<vector<int> > ret; ret.clear(); if (root == NULL) return ret; queue<Node> q; q.push(Node(root, 0)); int curLevel = -1; vector<int> a; while(!q.empty()) { Node node = q.front(); if (node.node->left) q.push(Node(node.node->left, node.level + 1)); if (node.node->right) q.push(Node(node.node->right, node.level + 1)); if (curLevel != node.level) { if (curLevel != -1) { if (curLevel % 2 == 1) reverse(a.begin(), a.end()); ret.push_back(a); } a.clear(); curLevel = node.level; } a.push_back(node.node->val); q.pop(); } if (curLevel % 2 == 1) reverse(a.begin(), a.end()); ret.push_back(a); return ret; } };
109. Convert Sorted List to Binary Search Tree
题意:将一个有序链表变成二叉搜索树
我的思路:dfs,类似108,找中间节点作为根,递归左右
我的代码:
class Solution { public: TreeNode* dfs(ListNode* head, int f, int t) { int mid = (f+t)/2, cnt = 0; ListNode* tmp = head; while (cnt < mid) { tmp = tmp->next; cnt++; } TreeNode* ret = new TreeNode(tmp->val); if (mid > f) ret->left = dfs(head, f, mid-1); if (mid < t) ret->right = dfs(head, mid+1, t); return ret; } TreeNode* sortedListToBST(ListNode* head) { int size = 0; ListNode* tmp = head; while (tmp) { size++; tmp = tmp->next; } if (size == 0) return NULL; return dfs(head, 0, size-1); } };
110. Balanced Binary Tree
题意:判Balanced Binary Tree,即每个节点的高度差不大于1
我的思路:常规dfs
我的代码:
class Solution { public: int maxdepth(TreeNode* root, int &ans) { if (root == NULL) return 0; int l = maxdepth(root->left, ans), r = maxdepth(root->right, ans); if (abs(l-r) > 1) ans = 0; return max(l, r)+1; } bool isBalanced(TreeNode* root) { int ans = 1; maxdepth(root, ans); return ans; } };
114. Flatten Binary Tree to Linked List
题意:将一个二叉树的前序遍历拉成只有右子树的链表状
我的思路:对于每个节点,将他的左子树放到右子树上,原来的右子树连到左子树最右下角
我的代码:
class Solution { public: void flatten(TreeNode* root) { while (root) { if (root->left) { TreeNode* tmp = root->left; while (tmp->right) tmp = tmp->right; tmp->right = root->right; root->right = root->left; root->left = NULL; } root = root->right; } } };
116. Populating Next Right Pointers in Each Node
题意:树结构体中增加一个next指针,将它指向同一层右边的节点,最右边那个指向空
我的思路:队列
我的代码:
class Solution { public: void connect(TreeLinkNode *root) { if (root == NULL) return; queue<TreeLinkNode *> q; q.push(root); while (!q.empty()) { TreeLinkNode *r = NULL; int n = q.size(); for (int i = 0; i < n; i++) { TreeLinkNode *tmp = q.front(); q.pop(); if (tmp->right) q.push(tmp->right); if (tmp->left) q.push(tmp->left); tmp->next = r; r = tmp; } } } };
117. Populating Next Right Pointers in Each Node II
题意:上题是满树,这次每层节点可能不满
我的思路:跟上题一个代码,不用考虑
124. Binary Tree Maximum Path Sum
题意:输出二叉树的最大路径和
我的思路:dfs
我的代码:
class Solution { public: int ans = 0x80000000; int dfs(TreeNode* root) { if (root == NULL) return 0; int l = dfs(root->left), r = dfs(root->right); ans = max(ans, root->val+max(l, 0)+max(r, 0)); return root->val+max(max(l, r), 0); } int maxPathSum(TreeNode* root) { dfs(root); return ans; } };
144. Binary Tree Preorder Traversal
题意:二叉树前序遍历
我的思路:递归水题
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void dfs(TreeNode* root, vector<int> &ans) { ans.push_back(root->val); if (root->left) dfs(root->left, ans); if (root->right) dfs(root->right, ans); } vector<int> preorderTraversal(TreeNode* root) { vector<int> ans; if (root) dfs(root, ans); return ans; } };
九章最优解:一样
class Solution { public: vector<int> preorder; void traverse(TreeNode *root) { if (root == NULL) { return; } preorder.push_back(root->val); traverse(root->left); traverse(root->right); } vector<int> preorderTraversal(TreeNode *root) { preorder.clear(); traverse(root); return preorder; } };
145. Binary Tree Postorder Traversal
题意:二叉树后序遍历
我的思路:递归水题
我的代码:
class Solution { public: void dfs(TreeNode* root, vector<int> &ans) { if (root->left) dfs(root->left, ans); if (root->right) dfs(root->right, ans); ans.push_back(root->val); } vector<int> postorderTraversal(TreeNode* root) { vector<int> ans; if (root == NULL) return ans; dfs(root, ans); return ans; } };
九章最优解:用栈不用递归
class Solution { public: vector<int> postorderTraversal(TreeNode *root) { vector<int> result; stack<TreeNode *> myStack; TreeNode *current = root, *lastVisited = NULL; while (current != NULL || !myStack.empty()) { while (current != NULL) { myStack.push(current); current = current->left; } current = myStack.top(); if (current->right == NULL || current->right == lastVisited) { myStack.pop(); result.push_back(current->val); lastVisited = current; current = NULL; } else { current = current->right; } } return result; } };
104. Maximum Depth of Binary Tree
题意:输出给定二叉树的最大深度
我的思路:dfs水题
我的代码:
class Solution { public: int ans = 0; void dfs(TreeNode* root, int depth) { if (root->left == NULL && root->right == NULL) { ans = max(ans, depth+1); return; } if (root->left) dfs(root->left, depth+1); if (root->right) dfs(root->right, depth+1); } int maxDepth(TreeNode* root) { if (root) dfs(root, 0); return ans; } };
九章最优解:同样dfs, 没人家写得好
class Solution { public: /** * @param root: The root of binary tree. * @return: An integer */ int maxDepth(TreeNode *root) { if (root == NULL) { return 0; } int left = maxDepth(root->left); int right = maxDepth(root->right); return left > right ? left + 1 : right + 1; } };
105. Construct Binary Tree from Preorder and Inorder Traversal
题意:由前序、中序遍历生成二叉树
我的思路:dfs寻找每个节点的前序、中序遍历,递归生成
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void dfs(TreeNode* root, vector<int>& preorder, vector<int>& inorder, int f1, int t1, int f2, int t2) { root->val = preorder[f1]; int i; for (i = f2; i <= t2; i++) { if (inorder[i] == preorder[f1]) break; } if (i > f2) root->left = new TreeNode(0), dfs(root->left, preorder, inorder, f1+1, i+f1-f2, f2, i-1); if (i < t2) root->right = new TreeNode(0), dfs(root->right, preorder, inorder, t1-t2+i+1, t1, i+1, t2); return; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { TreeNode* root; if (preorder.size() == 0) return root; root = new TreeNode(0); dfs(root, preorder, inorder, 0, preorder.size()-1, 0, inorder.size()-1); cout<<root->val<<endl; return root; } };
九章最优解:思路一样,写法完爆
class Solution { /** *@param preorder : A list of integers that preorder traversal of a tree *@param inorder : A list of integers that inorder traversal of a tree *@return : Root of a tree */ public: typedef vector<int>::iterator Iter; TreeNode *buildTreeRecur(Iter istart, Iter iend, Iter pstart, Iter pend) { if(istart == iend)return NULL; int rootval = *pstart; Iter iterroot = find(istart, iend, rootval); TreeNode *res = new TreeNode(rootval); res->left = buildTreeRecur(istart, iterroot, pstart+1, pstart+1+(iterroot-istart)); res->right = buildTreeRecur(iterroot+1, iend, pstart+1+(iterroot-istart), pend); return res; } TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) { // write your code here return buildTreeRecur(inorder.begin(), inorder.end(), preorder.begin(), preorder.end()); } };
106. Construct Binary Tree from Inorder and Postorder Traversal
题意:由中序后序遍历恢复二叉树
我的思路:dfs,跟上题一样
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: typedef vector<int>::iterator Iter; TreeNode *dfs(Iter istart, Iter iend, Iter pstart, Iter pend) { if (istart == iend) return NULL; int val = *(pend-1); Iter root = find(istart, iend, val); TreeNode *res = new TreeNode(val); res->left = dfs(istart, root, pstart, pstart+(root-istart)); res->right = dfs(root+1, iend, pstart+(root-istart), pend-1); return res; } TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { return dfs(inorder.begin(), inorder.end(), postorder.begin(), postorder.end()); } };
九章最优解:一样
108. Convert Sorted Array to Binary Search Tree
题意:将有序数列转化为二分搜索树
我的思路:dfs1A
我的代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* dfs(vector<int>& nums, int f, int t) { int mid = (f+t)/2; TreeNode* ret = new TreeNode(nums[mid]); if (mid > f) ret->left = dfs(nums, f, mid-1); if (mid < t) ret->right = dfs(nums, mid+1, t); return ret; } TreeNode* sortedArrayToBST(vector<int>& nums) { if (nums.size() == 0) return NULL; return dfs(nums, 0, nums.size()-1); } };
九章最优解:一样
111. Minimum Depth of Binary Tree
题意:求二叉树的最小深度,即根节点到叶子结点的最小距离
我的思路:bfs水题
我的代码:
class Solution { public: int minDepth(TreeNode* root) { if (root == NULL) return 0; int ans = 0, flag = 1; queue<TreeNode*> que; que.push(root); while (flag) { int cnt = que.size(); ans++; while (cnt--) { TreeNode* tmp = que.front(); que.pop(); if (tmp->left == NULL && tmp->right == NULL) { flag = 0; break; } if (tmp->left) que.push(tmp->left); if (tmp->right) que.push(tmp->right); } } return ans; } };
九章最优解:dfs,递归返回左子树和右子树深度较小的
class Solution { public: /** * @param root: The root of binary tree. * @return: An integer */ int ans; int solve_dp(TreeNode *root) { if(root == NULL) return 0; if (root->left == NULL && root->right == NULL) return 1; int lf = 0x7fffffff, rt = 0x7fffffff; if(root->left) lf = solve_dp(root->left); if(root->right) rt = solve_dp(root->right); return min(lf, rt) + 1; } int minDepth(TreeNode *root) { // write your code here if (!root) return 0; return solve_dp(root); } };
112. Path Sum
题意:求是否有根节点到叶子结点的值之和为sum
我的思路:dfs1A,但是写的很不好
我的代码:
class Solution { public: bool dfs(TreeNode* root, int sum, int tmp) { tmp += root->val; if (root->left == NULL && root->right == NULL && tmp == sum) return 1; if (root->left && root->right) return dfs(root->left, sum, tmp) || dfs(root->right, sum, tmp); else if (root->left) return dfs(root->left, sum, tmp); else if (root->right) return dfs(root->right, sum, tmp); return 0; } bool hasPathSum(TreeNode* root, int sum) { if (root == NULL) return 0; return dfs(root, sum, 0); } };
九章最优解:
public class Solution { public boolean hasPathSum(TreeNode root, int sum) { if (root == null) { return false; } if (root.left == null && root.right == null) { return sum == root.val; } return hasPathSum (root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); } }
113. Path Sum II
题意:返回根节点到叶节点值之和为sum的所有路径
我的思路:dfs1A
我的代码:
class Solution { public: vector<vector<int>> ans; void dfs(TreeNode* root, int sum, int cnt, vector<int> tmp) { cnt += root->val; tmp.push_back(root->val); if (root->left == NULL && root->right == NULL && cnt == sum) ans.push_back(tmp); if (root->left) dfs(root->left, sum, cnt, tmp); if (root->right) dfs(root->right, sum, cnt, tmp); } vector<vector<int>> pathSum(TreeNode* root, int sum) { if (root == NULL) return ans; vector<int> tmp; dfs(root, sum, 0, tmp); return ans; } };
九章最优解:思路一样,代码只有java的
public class Solution { public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) { ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> solution = new ArrayList<Integer>(); findSum(rst, solution, root, sum); return rst; } private void findSum(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> solution, TreeNode root, int sum){ if (root == null) { return; } sum -= root.val; if (root.left == null && root.right == null) { if (sum == 0){ solution.add(root.val); result.add(new ArrayList<Integer>(solution)); solution.remove(solution.size()-1); } return; } solution.add(root.val); findSum(result, solution, root.left, sum); findSum(result, solution, root.right, sum); solution.remove(solution.size()-1); } }
129. Sum Root to Leaf Numbers
题意:每个从根到叶的路径生成一个数,根是高位,求这些数的和
我的思路:递归水题1A
我的代码:
class Solution { public: int ans; void dfs(TreeNode* root, int tmp) { tmp = tmp*10+root->val; if (root->left == NULL && root->right == NULL) { ans += tmp; return; } if (root->left) dfs(root->left, tmp); if (root->right) dfs(root->right, tmp); } int sumNumbers(TreeNode* root) { if (root == NULL) return 0; dfs(root, 0); return ans; } };
199. Binary Tree Right Side View
题意:给定一棵二叉树,输出从右往左看到的数字
我的思路:dfs,记录层数,先dfs右子树,再dfs左子树
我的代码:
class Solution { public: void dfs(TreeNode* root, vector<int> &ans, int i) { if (i > ans.size()) ans.push_back(root->val); if (root->right) dfs(root->right, ans, i+1); if (root->left) dfs(root->left, ans, i+1); } vector<int> rightSideView(TreeNode* root) { vector<int> ans; if (root) dfs(root, ans, 1); return ans; } };
222. Count Complete Tree Nodes
题意:数完全二叉树的节点数
我的思路:dfs,bfs都会超时,要利用完全二叉树节点数的特点,递归找左右子树深度相同的子树可以直接计算出个数
我的代码:
class Solution { public: int countNodes(TreeNode* root) { if (!root) return 0; int l = 1, r = 1; TreeNode* r1 = root, *r2 = root; while (r1->left) { l++; r1 = r1->left; } while (r2->right) { r++; r2 = r2->right; } if (l == r) return pow(2, l)-1; return 1+countNodes(root->left)+countNodes(root->right); } };
226. Invert Binary Tree
题意:翻转一棵二叉树
我的思路:
class Solution { public: TreeNode* invertTree(TreeNode* root) { if (root == NULL) return root; TreeNode* tmp = root->right; root->right = root->left; root->left = tmp; if (root->left) invertTree(root->left); if (root->right) invertTree(root->right); return root; } };
230. Kth Smallest Element in a BST
题意:输出二叉搜索树中第k小的数
我的思路:利用BST的中序遍历是一个递增序列,dfs
我的代码:
class Solution { public: int cnt, ans; void dfs(TreeNode* root, int k) { if (root->left) dfs(root->left, k); cnt++; if (cnt == k) { ans = root->val; return; } if (root->right) dfs(root->right, k); } int kthSmallest(TreeNode* root, int k) { if (root) dfs(root, k); return ans; } };
235. Lowest Common Ancestor of a Binary Search Tree
题意:给定一棵二叉搜索树,及两个节点,输出两节点最近祖先的值
我的思路:第一个在两个值之间的节点就是他俩的最近祖先
我的代码:
class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (p->val > q->val) { TreeNode* tmp = q; q = p; p = tmp; } while (root) { if (root->val >= p->val && root->val <= q->val) return root; else if (root->val > q->val) root = root->left; else root = root->right; } } };
236. Lowest Common Ancestor of a Binary Tree
题意:返回二叉树的最低祖先
我的思路:递归检查
我的代码:
class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (!root || root == p || root == q) return root; TreeNode* l = lowestCommonAncestor(root->left, p, q); TreeNode* r = lowestCommonAncestor(root->right, p, q); if (l && r) return root; return l == NULL ? r : l; } };
297. Serialize and Deserialize Binary Tree
题意:将一棵二叉树编成一个序列并且能够解码
我的思路:前序遍历编码,dfs解码
我的代码:
/** * 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: // Encodes a tree to a single string. string serialize(TreeNode* root) { if (root == NULL) return "#"; return to_string(root->val)+","+serialize(root->left)+","+serialize(root->right); } // Decodes your encoded data to tree. TreeNode* reconduct(string &data) { if (data[0] == '#') { if (data.size() > 1) data = data.substr(2); return NULL; } int i = 0, n = 0; if (isdigit(data[i]) || data[i] == '-') { int k = 1; if (data[i] == '-') k = -1, i++; while (isdigit(data[i])) { n = n*10+data[i]-'0'; i++; } n = n*k; } TreeNode* ret = new TreeNode(n); data = data.substr(i+1); ret->left = reconduct(data); ret->right = reconduct(data); return ret; } TreeNode* deserialize(string data) { return reconduct(data); } }; // Your Codec object will be instantiated and called as such: // Codec codec; // codec.deserialize(codec.serialize(root));
310. Minimum Height Trees
题意:给定一个无向图,不含重边,输出使它成为高度最小的树的根节点
思路:discuss第一个,bfs
我的代码:
class Solution { public: vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) { if (n == 1) return {0}; vector<unordered_set<int>> e(n); vector<unordered_set<int>::iterator> it(n); for (int i = 0; i < edges.size(); i++) { e[edges[i].first].insert(edges[i].second); e[edges[i].second].insert(edges[i].first); } vector<int> ans; for (int i = 0; i < n; i++) { it[i] = e[i].begin(); if (e[i].size() == 1) ans.push_back(i); } while (n > 2) { n -= ans.size(); vector<int> tmp; for (int i : ans) for (int j : e[i]) { e[j].erase(i); if (e[j].size() == 1) tmp.push_back(j); } ans = tmp; } return ans; } };
337. House Robber III
题意:从树上取值,不能去相邻节点,求可以取得的总数最大值
我的思路:dfs,每个节点记录有他的最大值和没他的最大值两个数,最后输出根节点两个值中较大的
我的代码:
class Solution { public: vector<int> dfs(TreeNode* root) { vector<int> ans(2, 0); if (!root) return ans; vector<int> tmp1 = dfs(root->left), tmp2 = dfs(root->right); ans[0] = max(tmp1[0], tmp1[1])+max(tmp2[0], tmp2[1]); ans[1] = tmp1[0]+tmp2[0]+root->val; return ans; } int rob(TreeNode* root) { vector<int> ans = dfs(root); return max(ans[0], ans[1]); } };
437. Path Sum III
题意:输出树有几条从上(不一定是根节点)到下(不一定是叶子)的路径和为sum
我的思路:dfs
我的代码:
class Solution { public: int dfs(TreeNode* root, int sum) { if (root == NULL) return 0; return (sum == root->val)+dfs(root->left, sum-root->val)+dfs(root->right, sum-root->val); } int pathSum(TreeNode* root, int sum) { if (root == NULL) return 0; return pathSum(root->left, sum)+pathSum(root->right, sum)+dfs(root, sum); } };
449. Serialize and Deserialize BST
题意:将排序二叉树序列化、解序列化
我的思路:跟297题用的一份代码
我的代码:
class Codec { public: // Encodes a tree to a single string. string serialize(TreeNode* root) { if (root == NULL) return "#"; return to_string(root->val)+","+serialize(root->left)+","+serialize(root->right); } // Decodes your encoded data to tree. TreeNode* reconduct(string &data) { if (data[0] == '#') { if (data.size() > 1) data = data.substr(2); return NULL; } int i = 0, n = 0; if (isdigit(data[i]) || data[i] == '-') { int k = 1; if (data[i] == '-') k = -1, i++; while (isdigit(data[i])) { n = n*10+data[i]-'0'; i++; } n = n*k; } TreeNode* ret = new TreeNode(n); data = data.substr(i+1); ret->left = reconduct(data); ret->right = reconduct(data); return ret; } TreeNode* deserialize(string data) { return reconduct(data); } };
450. Delete Node in a BST
题意:删除二叉搜索树中等于某个值的节点
我的思路:递归
我的代码:
class Solution { public: int findmin(TreeNode* root) { while (root->left) root = root->left; return root->val; } TreeNode* deleteNode(TreeNode* root, int key) { if (root == NULL) return root; if (root->val > key) root->left = deleteNode(root->left, key); else if (root->val < key) root->right = deleteNode(root->right, key); else { if (root->left == NULL) return root->right; if (root->right == NULL) return root->left; root->val = findmin(root->right); root->right = deleteNode(root->right, root->val); } return root; } };
530. Minimum Absolute Difference in BST
题意:输出二叉搜索树任意两节点间的最小差值的绝对值
我的思路:每个节点找比他小的最大的和比他大的最小的,结果是二者之一
我的代码:
class Solution { public: int getmax(TreeNode* root) { while (root->right) root = root->right; return root->val; } int getmin(TreeNode* root) { while (root->left) root = root->left; return root->val; } void dfs(TreeNode* root, int& ans) { if (!root) return; if (root->left) { ans = min(ans, abs(getmax(root->left)-root->val)); dfs(root->left, ans); } if (root->right) { ans = min(ans, abs(root->val-getmin(root->right))); dfs(root->right, ans); } } int getMinimumDifference(TreeNode* root) { int ans = 0x7fffffff; dfs(root, ans); return ans; } };
501. Find Mode in Binary Search Tree
题意:找出二叉搜索树中频率最高的数,要求空间复杂度O1
我的思路:中序遍历
我的代码:
class Solution { public: TreeNode* pre = NULL; void dfs(TreeNode* root, vector<int>& ans, int& cnt, int& maxn) { if (!root) return; if (root->left) dfs(root->left, ans, cnt, maxn); if (pre != NULL) { if (root->val == pre->val) cnt++; else cnt = 1; } if (cnt >= maxn) { if (cnt > maxn) ans.clear(); ans.push_back(root->val); maxn = cnt; } pre = root; if (root->right) dfs(root->right, ans, cnt, maxn); } vector<int> findMode(TreeNode* root) { vector<int> ans; if (!root) return ans; int cnt = 1, maxn = 0; dfs(root, ans, cnt, maxn); return ans; } };
538. Convert BST to Greater Tree
题意:将一个二叉搜索树的每个节点值加上所有大于他的值
我的思路:dfs
我的代码:
class Solution { public: int sum; void dfs(TreeNode* root) { if (root->right) dfs(root->right); sum += root->val; root->val = sum; if (root->left) dfs(root->left); } TreeNode* convertBST(TreeNode* root) { if (root == NULL) return root; dfs (root); return root; } };
九章最优解:一样
563. Binary Tree Tilt
题意:常规dfs
题意:判断一个树是否是另一个树的子树
我的思路:递归
我的代码:
View Code
617. Merge Two Binary Trees
题意:将两棵二叉树的节点值相加,不同的边补出
我的思路:蜜汁通过
class Solution { public: TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { if (t1 && t2) { t1->val += t2->val; t1->left = mergeTrees(t1->left, t2->left); t1->right = mergeTrees(t1->right, t2->right); } else if (t1 == NULL && t2) t1 = t2; return t1; } };
solution解法:差不多
class Solution { public: TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { if (!t2) return t1; if (!t1) return t2; t1->val += t2->val; t1->left = mergeTrees(t1->left, t2->left); t1->right = mergeTrees(t1->right, t2->right); return t1; } };
637. Average of Levels in Binary Tree
题意:输出二叉树每一层的平均值
我的思路:bfs
我的代码:
class Solution { public: vector<double> averageOfLevels(TreeNode* root) { vector<double> ans; if (root == NULL) return ans; queue<TreeNode*> q; q.push(root); while (!q.empty()) { ans.push_back(0); int n = q.size(), m = ans.size(); for (int i = 0; i < n; i++) { TreeNode* tmp = q.front(); q.pop(); ans[m-1] += tmp->val; if (tmp->left) q.push(tmp->left); if (tmp->right) q.push(tmp->right); } ans[m-1] /= n; } return ans; } };
655. Print Binary Tree
题意:将二叉树打印为二维矩阵
我的思路:先bfs求个层数,就知道了矩阵维度,再dfs改变矩阵元素
我的代码:
class Solution { public: void dfs(TreeNode* root, vector<vector<string>>& ans, int l, int f, int t) { ans[l][(f+t)/2] = to_string(root->val); if (root->left) dfs(root->left, ans, l+1, f, (f+t)/2-1); if (root->right) dfs(root->right, ans, l+1, (f+t)/2+1, t); } vector<vector<string>> printTree(TreeNode* root) { if (!root) return {{""}}; int depth = 0; queue<TreeNode*> q; q.push(root); while (!q.empty()) { int n = q.size(); depth++; for (int i = 0; i < n; i++) { TreeNode* tmp = q.front(); q.pop(); if (tmp->left) q.push(tmp->left); if (tmp->right) q.push(tmp->right); } } vector<vector<string>> ans(depth, vector<string>(pow(2, depth)-1)); dfs(root, ans, 0, 0, pow(2, depth)-2); return ans; } };
662. Maximum Width of Binary Tree
题意:输出二叉树的最大宽度,宽度即每层最左节点到最右节点
我的思路:只需要按照完全二叉树节点的计数方法保存每个节点在整棵二叉树中的位置下标,一般当前位置是i,则其左孩子节点的下标为2*i,其右孩子下标为2*i+1。所以最后只需要将每一层中最大的孩子的下标数-开始的最小孩子的下标数,就是最大宽度,采用层次遍历的方法来执行即可。
我的代码:
class Solution { public: int widthOfBinaryTree(TreeNode* root) { if (!root) return 0; queue<TreeNode*> qr; vector<int> qn; int ans = 1; qr.push(root); qn.push_back(1); while (!qr.empty()) { ans = max(ans, qn[qn.size()-1]-qn[0]+1); int n = qr.size(); for (int i = 0; i < n; i++) { TreeNode* tmp = qr.front(); qr.pop(); int id = qn[0]; qn.erase(qn.begin()); if (tmp->left) { qr.push(tmp->left); qn.push_back(id<<1); } if (tmp->right) { qr.push(tmp->right); qn.push_back(id<<1|1); } } } return ans; } };