Day21——二叉树Ⅶ
今日内容
● 530.二叉搜索树的最小绝对差
● 501.二叉搜索树中的众数
● 236.二叉树的最近公共祖先
530.二叉搜索树的最小绝对差
思路:差值最小,一定是有序数组中的相邻元素。中序遍历,每次记录上一节点值和两节点差值。
中序遍历写了半天,后来发现栈用成了队列
int getMinimumDifference(TreeNode* root) {
if(root == nullptr) return 0;
stack<TreeNode*> st;
TreeNode* cur = root;
int pre = INT_MAX;
int diff = INT_MAX;
while(!st.empty() || cur != nullptr) {
if(cur != nullptr) {
st.push(cur);
cur = cur->left;
} else {
cur = st.top();
st.pop();
diff = min(abs(pre - cur->val), diff);
pre = cur->val;
cur = cur->right;
}
}
return diff;
}
501.二叉搜索树中的众数
思路: 遍历,unordered_map记录出现频率,再遍历map选出最大值。
没有想清楚二叉搜索树和二叉树在这里的区别
这里就写一下给map排序的方法吧
bool cmp(const pair<int, int>& p1, const pair<int, int>& p2) {
return p1.second > p2.second;
}
unordered_map<int, int> dp;
···
// 排序
vector<pair<int, int>> res(dp.begin(), dp.end());
sort(res.begin(), res.end(), mySort);
看了题解,思路二,中序遍历,如果为众数肯定相邻,记录最大相邻元素个数,大于最大值清空res并更新,等于直接加入。
vector<int> findMode(TreeNode* root) {
vector<int> res;
if(root == nullptr) return res;
stack<treeNode*> st;
TreeNode* cur = root;
TreeNode* pre = nullptr;
int count = 0;
int maxCount = 0;
while(!st.empty() || cur != nullptr) {
if(cur != nullptr) {
st.push(cur);
cur = cur->left;
} else {
cur = st.top();
st.pop();
if(pre == nullptr) count = 1;
else if(pre->val == cur->val) ++count;
else count = 1;
if(count == maxCount) {
res.push_back(cur->val);
}
if(count > maxCount) {
maxCount = count;
res.clear();
res.push_back(cur->val);
}
}
}
return res;
}
236.二叉树的最近公共祖先
代码很短,但是理解挺难。
递归结束条件 1. 空树 2. p是q孩子或者q是p孩子并且找到了这个节点。(题目定义一定有两个节点)
找最近公共祖先,首先想到的是自底向上遍历,后序遍历(回溯)刚好满足条件
让左孩子和右孩子都返回是否存在孩子(存在则返回孩子),如果左孩子和右孩子都不为空,说明root就是最近祖先,因为只有两个孩子,一左一右,不能再近了。如果其中一个为空,那么公共祖先一定在另一个孩子,因为一定有公共祖先。
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == p || root == q || root == nullptr) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left != nullptr && right != nullptr) return root;
else if(left != nullptr) return left;
else return right;
}