【代码随想录算法训练营第二十天|530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、 236. 二叉树的最近公共祖先】

代码随想录算法训练营第二十天|530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、 236. 二叉树的最近公共祖先

  • 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。

总结:凡是碰见二叉搜索树的问题,都要结合性质考虑,并使用中序遍历。

你可能感兴趣的:(算法,深度优先)