代码随想录算法训练营第二十天|530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、 236. 二叉树的最近公共祖先
解题思路和代码来源:
《代码随想录》:https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html#%E6%80%9D%E8%B7%AF
y总:http://acwing.com
530.二叉搜索树的最小绝对差
我是一看就会,一写就废,先看代码:
class Solution {
public:
int res = INT_MAX,last;
bool is_first = true;
int getMinimumDifference(TreeNode* root) {
dfs(root);
return res;
}
void dfs(TreeNode* root)
{
if(!root) return;
dfs(root->left);
if(is_first) is_first = false;
else res = min(res,root->val - last);
last = root->val;
dfs(root->right);
}
};
这道题目的题意就是寻找搜索二叉树中差点绝对值最小的,这里我看的y总的思路,首先还是要看题目中给的是二叉搜索树,搜索二叉树的特性是左子树都小于根,右子树都大于根,中序遍历的话就是一个递增数组,所以前一个数就肯定比后一个数小,所以用后一个数减去前一个数,找到差值最小的就行,不用求绝对值了,这是y总巧妙的地方。 这里第一个数需要单独处理,第一个数因为没有前一个数,所以遇到第一个数就让它直接当作last,这里学会了一个新的方法,就是使用一个bool变量来控制。
501.二叉搜索树中的众数
先看代码:
class Solution {
public:
vector<int> ans;
int maxc = 0,curc = 0,last;
vector<int> findMode(TreeNode* root) {
dfs(root);
return ans;
}
void dfs(TreeNode* root)
{
if(!root) return;
dfs(root->left);
if(!curc || root->val == last)
{
curc++;
last = root->val;
}
else
{
last = root->val;
curc = 1;
}
if(curc > maxc)
{
ans = {last};
maxc = curc;
}
else if(curc == maxc) ans.push_back(last);
dfs(root->right);
}
};
这道找众数的题目我觉得很巧妙首先要明白这还是二叉搜索树,仍然是它的特性,左边永远小于根,右边永远大于根,所以如果某个数是众数的话,它一定也是一段区间,我们只要记录这段区间就可以了,首先从第一个开始,然后用last记录上一个数的值。用maxc来记录最大的次数,用curc来记录当前的次数,如果当前的次数比最大次数大,说明新的众数出现了,这个时候除了要更新的maxc,新王还要登基。如果有多个众数,那就再添加就可以了,而不是替换。
236. 二叉树的最近公共祖先
先看代码:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL || root->val == p->val || root->val == q->val) 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;
else return right;
}
};
这个题目我觉得代码随想录的思路更加的好,就是入过某一个节点的子树中包含p,q两个节点,就公共的根节点。y总其实也是这个意思,只不过用了一个state来记录,00表示都没有,10表示只有p,01表示只有q,11表示既有p也有q。
总结:凡是碰见二叉搜索树的问题,都要结合性质考虑,并使用中序遍历。