代码随想录算法训练营43期 | Day 18——530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数

20 篇文章 0 订阅

代码随想录算法训练营43期 | Day 18

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

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。

解题思路

双指针实现二叉搜索树相邻节点的最小绝对值差
二叉搜索树:有序的序列
中序遍历:得到的是有序的数列
将二叉搜索树得到有序的数组,在求两个元素的最小绝对差

class Solution {
public:
    vector<int> result;
    void traversal(TreeNode* root)
    {
        if(root==nullptr) return;
        //遍历 左
        traversal(root->left);
        result.push_back(root->val);
        traversal(root->right);
    }

    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        //判断数组中是否含有数组长度<2
        if(result.size()<2) return 0;
        //遍历数组
        int res = INT_MAX;
        for(int i=1;i<result.size();i++)
        {
            res = min(res, result[i]-result[i-1]);
        }
        return res;
    }
};

** 方法二 :利用两个指针:**
如何控制两个指针,遍历二叉搜索树

class Solution {
public:
    //记录相邻节点绝对值最小值
    int result = INT_MAX;
    TreeNode* pre = nullptr;
    //函数参数和返回值
    void traversal(TreeNode* cur)
    {
        if(cur==nullptr) return ;
        //左遍历
        traversal(cur->left);
        //中的处理逻辑
        if(pre!=nullptr)
        {
            result = min(result, cur->val-pre->val);
        }
        pre = cur;
        //右遍历
        traversal(cur->right);
    }

    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return result;
    }
};

501.二叉搜索树中的众数

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:

  1. 结点左子树中所含结点的值小于等于当前结点的值
  2. 结点右子树中所含结点的值大于等于当前结点的值
  3. 左子树和右子树都是二叉搜索树

中序遍历,得到的一个有序的序列,然后从扫描这个中序遍历序列,然后用一个哈希表来统计每个数字出现的个数,这样就可以找到出现次数最多的数字。

但是,这样一颗二叉搜索树的中序遍历序列是 {−1,0,0,1,2,2}。

我们可以发现重复出现的数字一定是一个连续出现的,例如这里的 0 和 2,它们都重复出现了,并且所有的 0 都集中在一个连续的段内,所有的 2 也集中在一个连续的段内。

我们可以顺序扫描中序遍历序列,用 base 记录当前的数字,用 count 记录当前数字重复的次数,用 maxCount 来维护已经扫描过的数当中出现最多的那个数字的出现次数,用 answer 数组记录出现的众数。每次扫描到一个新的元素:

  • 首先更新 base 和 count:
    如果该元素和 base 相等,那么 count 自增 1;
    否则将 base 更新为当前数字,count 复位为 1。
  • 然后更新 maxCount:
    如果 count=maxCount,那么说明当前的这个数字(base)出现的次数等于当前众数出现的次数,将 base 加入 answer 数组;
    如果 count>maxCount,那么说明当前的这个数字(base)出现的次数大于当前众数出现的次数,因此,我们需要将 maxCount 更新为 count,清空 answer 数组后将 base 加入 answer 数组。
class Solution {
private:
    int maxCount = 0; // 所有元素最大频率
    int count = 0; // 统计单个元素频率
    TreeNode* pre = NULL;
    vector<int> result;
    void searchBST(TreeNode* cur) {
        if (cur == NULL) return ;

        searchBST(cur->left);       // 左
                                    // 中
        if (pre == NULL) { // 第一个节点
            count = 1;
        } else if (pre->val == cur->val) { // 与前一个节点数值相同
            count++;
        } else { // 与前一个节点数值不同
            count = 1;
        }
        pre = cur; // 更新上一个节点

        if (count == maxCount) { // 如果和最大值相同,放进result中
            result.push_back(cur->val);
        }

        if (count > maxCount) { // 如果计数大于最大值频率
            maxCount = count;   // 更新最大频率
            result.clear();     // 很关键的一步,不要忘记清空result,之前result里的元素都失效了
            result.push_back(cur->val);
        }

        searchBST(cur->right);      // 右
        return ;
    }

public:
    vector<int> findMode(TreeNode* root) {
        count = 0;
        maxCount = 0;
        pre = NULL; // 记录前一个节点
        result.clear();

        searchBST(root);
        return result;
    }
};

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值