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

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

题目链接:LeetCode 530. 二叉搜索树的最小绝对差

class Solution {
private:
    vector<int> vec;
    void traversal(TreeNode* root)
    {
        if(root == NULL)
        return;
        traversal(root -> left);
        vec.push_back(root -> val);
        traversal(root -> right);
    }
    
public:
    int getMinimumDifference(TreeNode* root) {
        vec.clear();
        traversal(root);
        if(vec.size() < 2)
        return 0;
        int res = INT_MAX;
        for(int i = 1; i < vec.size(); i++)
        {
            res = min(vec[i] - vec[i - 1],res);
        }
        return res;
    }
};

思路: 首先利用二叉搜索树的特性:(根节点比所有左子树的节点值大,根节点比所有右子树的节点值小),将二叉树转化为有序数组再比较数组中相邻元素的差值便可得到二叉搜索树的最小绝对差。

小结:

1.该题的特判为:当数组大小小于2,即二叉树的节点小于2时,最小差值为0。

2.最小差值的初始值应该将其设置为无穷大


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

题目链接:LeetCode 501. 二叉搜索树中的众数

class Solution {
private:
    int count = 0;//设置计数器
    int maxcount = 0;//最大出现次数
    TreeNode* pre = NULL;//双指针
    vector<int> res;//结果集
    void traversal(TreeNode* root)
    {
        if(root == NULL)
        return;//根节点为空节点时终止遍历
        traversal(root -> left);
        if(pre == NULL)
        count = 1;//前指针指向空,即根节点为叶子节点时,记录出现次数为1
        else if(pre -> val == root -> val)
        count++;//双指针的值相等时,出现次数加1
        else
        count = 1;//双指针值不等时,更新计数器
        pre = root;//移动前指针
        if(count == maxcount)
        res.push_back(root -> val);//出现次数为记录的最大出现次数时,将值存入结果集
        if(count > maxcount)//出现次数大于记录的最大出现次数时
        {
            maxcount = count;//更新最大出现次数
            res.clear();//清空结果集
            res.push_back(root -> val);//存入新的值
        }
        traversal(root -> right);//中序遍历二叉搜索树
    }
public:
    vector<int> findMode(TreeNode* root) {
        count = 0;
        maxcount = 0;
        pre = NULL;
        res.clear();
        traversal(root);
        return res;
    }
};

思路:利用二叉搜索树的特性,我们可以考虑中序遍历,终止调节为遍历到空节点。利用双指针对前一个节点进行保存,再比较当前节点与前一个节点的值是否相等,同时记录某个值的出现次数与最大出现次数。在之后的遍历中,如果有与最大出现次数相同的值,则存入结果集中;否则更新最大出现次数,将结果集清空,存入新的值

小结:此方法只需要进行一次遍历,更新最大出现次数的同时也在寻找出现次数与最大出现次数相同的值。


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

题目链接:LeetCode 236. 二叉树的最近公共祖先

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)//当遍历到空节点时返回空节点
        return root;
        if(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;//左右节点中有一个节点为空,则返回不为空的节点
        else if(left == NULL && right != NULL)
        return right;
        else
        return NULL;//均为空返回空节点
    }
};

思路:通过后序遍历实现自下向上的遍历,如果寻找到目标节点,则返回该节点(记作左右节点);无目标节点则返回空。故每遍历一个根节点时会得到两个节点left和right,为目标节点时则一直返回该节点,否则返回空节点。当左右均不为空时,便找到了最近公共祖先,将其返回即可。

小结:这其中有一种特殊情况,即某一目标节点为两个目标节点的公共节点,此时,我们只需遍历到为公共节点的节点,便将其返回即可,上述代码已经包含了该种情况的处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值