501. 二叉搜索树中的众数

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

假定 BST 有如下定义:

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

 

官方解答:

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

首先更新 base 和 count:

如果该元素和 base 相等,那么 count 自增 11

否则将base 更新为当前数字,count 复位为 11

然后更新 maxCount

如果  maxCountcount=maxCount,那么说明当前的这个数字base出现的次数等于当前众数出现的次数,将 base 加入 answer 数组;
如果 count>maxCount,那么说明当前的这个数字base出现的次数大于当前众数出现的次数,因此,我们需要将maxCount 更新为 count,清空 answer 数组后将 base 加入 answer 数组。
我们可以把这个过程写成一个 handle 函数。这样我们在寻找出现次数最多的数字的时候就可以省去一个哈希表带来的空间消耗。

class Solution {
     vector<int>answer;
    
    int base, count, maxCount;
    
    void handle(int x){
        //有该元素就增加1
        if (x == base) {
            ++count;
        }else{//反正则重置1
            count = 1;
            base = x;
        }
        
        if (count == maxCount) {
            answer.push_back(base);
        }
        
        if (count > maxCount) {
            maxCount = count;
            answer = vector<int> {base};
        }
    }
    
    void deepfirstsearch(TreeNode * root){
        if (!root) {
            return;
        }
        
        deepfirstsearch(root->left);
        handle(root->val);
        deepfirstsearch(root->right);
    }
public:
    vector<int> findMode(TreeNode* root) {
        deepfirstsearch(root);
        return answer;
    }
};

时间复杂度O(N),空间复杂度O(N)

002 解法二:记录下每个节点出现的次数

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        vector<pair<int, int>> rec;

        auto append = [&](int v, int cnt) {
            if (cnt <= 0) {
                return;
            }
            if (rec.empty() || cnt > rec.back().second) {
                rec.clear();
                rec.push_back({v, cnt});
            } else if (cnt == rec.back().second) {
                rec.push_back({v, cnt});
            }
        };

        int preValue = 0;
        int preCnt = 0;
        stack<TreeNode *> t;
        while (root || !t.empty()) {
            while (root) {
                t.push(root);
                root = root->left;
            }

            root = t.top();
            t.pop();

            if (preValue == root->val) {
                preCnt++;
            } else {
                // 如果不相等,那么需要{preValue, preCnt}
                // 放到rec中
                append(preValue, preCnt);
                preValue = root->val;
                preCnt = 1;
            }

            root = root->right;
        }

        append(preValue, preCnt);

        vector<int> ans;
        for (auto &p : rec) ans.push_back(p.first);

        return ans;
    }
};

时间复杂度O(N),空间复杂度O(N)

题目

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值