代码随想录算法训练营第21天

LeetCode 530. 二叉搜索树的最小绝对差

解法一

思路:将二叉搜索树可以看作一个从小到大排列的有序数组,相邻数比较大小,就简单多了

class Solution {
public:
    vector<int> vec;
    void traversal(TreeNode* root){
        if(!root)return ;
        traversal(root->left);
        vec.push_back(root->val);
        traversal(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        int result=INT_MAX;
        traversal(root);
        for(int i=1;i<vec.size();i++){
            result=result<vec[i]-vec[i-1] ? result:vec[i]-vec[i-1];
        }
        return result;
    }
};

解法二

class Solution {
public:
    int result=INT_MAX;
    TreeNode* pre=NULL;
    void traversal(TreeNode* root){
        if(!root)return ;
        traversal(root->left);
        if(pre)result=min(result,root->val-pre->val);
        pre=root;
        traversal(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return result;
    }
};

这里用中序遍历,符合从大到小的顺序。
pre指向的是遍历的前一个节点,记录每一个前面的节点,后面-前面。

LeetCode 501. 二叉搜索树中的众数

解法一

class Solution {
public:
    unordered_map<int,int> map;
    void serchBST(TreeNode* root){
        if(!root)return ;
        map[root->val]++;
        serchBST(root->left);
        serchBST(root->right);

    }
    bool static cmp(pair<int,int>& a,pair<int,int>& b){
        return a.second>b.second;
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> result;
        if(!root)return result;

        serchBST(root);
        vector<pair<int,int>> vec(map.begin(),map.end());
        sort(vec.begin(),vec.end(),cmp);
        
        result.push_back(vec[0].first);
        for(int i=1;i<vec.size();i++){
            if(vec[i].second==vec[0].second)result.push_back(vec[i].first);
            else break;
        }
        return result;
    }
};

这种解法是通用解法,并没有体现出二叉搜索树的特点。
就是全部遍历一遍,哪种遍历方法都可以,然后将数出现频率存储到map中,根据键值对存储频率排序,由大到小添加到result数组中输出。

LeetCode 236. 二叉树的最近公共祖先

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==NULL || root==p || root==q)return root;
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        if(left!=NULL && right!=NULL)return root;
        else if(left!=NULL || right!=NULL)return left!=NULL ? left:right;
        else return NULL;
    }
};

这个题目比较牛,回溯的思想比较独特,我看完代码看了几遍都不能一下子理解。

  1. 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。这一点很重要,中节点的状态需要通过左子树,右子树来判断。所以回溯只能用后序遍历来做。
  2. 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
  3. 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。

具体代码思路,记录找到的最近公共祖先位置,然后不断将这个位置进行向上返回,left和right只要找到了所要求的位置,所记录的节点实际上就不会变了,left和right就不断向上返回,返回的其实都是同一个节点,即被记录的节点,只不过它可能以left或right的形式出现

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值