530.二叉搜索树的最小绝对差
代码随想录链接
题目
![](2023-03-07T121427.png)
返回给定的二叉搜索树内, 节点之间最小的差值.
自己的思路
二叉搜索树的中序遍历的结果是有序的, 在其中中找相邻值最小的即可.
题解
递归法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { private: vector<int> result; void traversal(TreeNode *root) { if (!root) return; traversal(root -> left); result.push_back(root -> val); traversal(root -> right); } public: int getMinimumDifference(TreeNode* root) { traversal(root); int minGap = INT_MAX; for (int i = 1; i < result.size(); i++) if (result[i] - result[i - 1] < minGap) minGap = result[i] - result[i - 1]; return minGap; } };
|
迭代法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { public: int getMinimumDifference(TreeNode* root) { if (!root) return 0; vector<int> result; stack<TreeNode*> st; st.push(root); while (!st.empty()) { TreeNode *node = st.top(); if (node) { st.pop();
if (node -> right) st.push(node -> right);
st.push(node); st.push(nullptr);
if (node -> left) st.push(node -> left); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node -> val); } } int minGap = INT_MAX; for (int i = 1; i < result.size(); i++) if (result[i] - result[i - 1] < minGap) minGap = result[i] - result[i - 1]; return minGap; } };
|
501.二叉搜索树中的众数
代码随想录链接
题目
![](2023-03-07T121748.png)
给定一个二叉搜索树, 返回其中的众数.
自己的思路
可以将全部节点遍历一遍, 通过map记录出现次数, 再进行排序得到,
但这样就和普通的二叉树没区别了.
二叉搜索树的中序遍历是有序的, 相同的数都会排在一起, 可以通过这个特性,
在中序遍历的基础上, 找到众数.
题解
递归法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { private: int maxCount = 0; int count = 0; TreeNode *pre = NULL; vector<int> result; void searchBST(TreeNode *cur) { if (cur == NULL) return; searchBST(cur -> left); if (pre == NULL) count = 1; else if (pre -> val == cur -> val) count++; else count = 1;
pre = cur;
if (count == maxCount) result.push_back(cur -> val);
if (count > maxCount) { maxCount = count; result.clear(); result.push_back(cur -> val); }
searchBST(cur -> right); } public: vector<int> findMode(TreeNode* root) { searchBST(root); return this -> result; } };
|
迭代法: (也是中序遍历,
甚至直接把上面对于中序遍历的中间节点的处理直接复制过来都没问题)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Solution { public: vector<int> findMode(TreeNode* root) { vector<int> result; if (!root) return result; int maxCount = 0; int count = 0; TreeNode *pre = nullptr; stack<TreeNode*> st; st.push(root); while (!st.empty()) { TreeNode *node = st.top(); if (node) { st.pop(); if (node -> right) st.push(node -> right); st.push(node); st.push(NULL); if (node -> left) st.push(node -> left); } else { st.pop(); node = st.top(); st.pop(); if (pre == NULL) count = 1; else if (pre -> val == node -> val) count++; else count = 1; pre = node; if (count == maxCount) result.push_back(node -> val); if (count > maxCount) { maxCount = count; result.clear(); result.push_back(node -> val); } } } return result; } };
|
236. 二叉树的最近公共祖先
代码随想录链接
题目
![](2023-03-07T122742.png)
给定一棵二叉树和其中的两个节点, 返回离这两个节点最近的公共祖先.
自己的思路
自己是想按照之前写二叉树的所有叶子路径那样来写这个题, 确实也实现了,
但是提交的时候就超时了.
看了卡尔哥的写法, 才发现不用写我那样复杂.
题解
自己想的通过遍历并记录路径来做的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if(!root) return nullptr; vector<vector<TreeNode*>> paths; vector<TreeNode*> p_path; vector<TreeNode*> q_path; stack<TreeNode*> st; st.push(root); paths.push_back(vector<TreeNode*>{root}); bool hasFoundp = false; bool hasFoundq = false; while (!st.empty() && (!hasFoundp || !hasFoundq)) { auto node = st.top(); st.pop(); auto path = paths.back(); paths.pop_back();
if (!hasFoundp && node == p) { hasFoundp = true; copy(path.begin(), path.end(), back_inserter(p_path)); }
if (!hasFoundq && node == q) { hasFoundq = true; copy(path.begin(), path.end(), back_inserter(q_path)); }
if (node -> right) { st.push(node -> right); path.push_back(node -> right); paths.push_back(path); path.pop_back(); }
if (node -> left) { st.push(node -> left); path.push_back(node -> left); paths.push_back(path); } } int pathLength = min(p_path.size(), q_path.size()); for (int i = 1; i < pathLength; i++) { if (p_path[i] != q_path[i]) return p_path[i - 1]; } if (p_path[pathLength - 1] == q_path[pathLength - 1]) return p_path[pathLength - 1]; return root; } };
|
卡尔哥的思路:
其实就是通过后序递归, 先找到p, q节点, 如果从左右子树里都找到了p, q,
那么在递归中首先满足这个条件的节点, 一定就是二者的最近公共祖先.
1 2 3 4 5 6 7 8 9 10 11 12
| class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (root == q || root == p || !root) return root; TreeNode *left = lowestCommonAncestor(root -> left, p, q); TreeNode *right = lowestCommonAncestor(root -> right, p, q); if (left && right) return root; if (left && !right) return left; if (!left && right) return right; return NULL; } };
|