算法笔记 -- 501. 二叉搜索树中的众数

70 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

一、题目描述:

501. 二叉搜索树中的众数 - 力扣(LeetCode)

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

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

示例 1:

image.png

输入:root = [1,null,2,2]
输出:[2]

示例 2:

输入:root = [0]
输出:[0]

提示:

  • 树中节点的数目在范围 [1, 10^4] 内
  • -10^5 <= Node.val <= 10^5  

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

二、思路分析:

二叉搜索树的中序遍历是一个升序序列,逐个比对当前结点(root)值与前驱结点(pre)值。更新当前节点值出现次数(curTimes)及最大出现次数(maxTimes)

更新规则:若curTimes=maxTimes,将root->val添加到结果向量(res)中;若curTimes>maxTimes,清空res(这一步是只用遍历一遍二叉树就能找到出现次数最多数的关键),将root->val添加到res,并更新maxTimes为curTimes。

三、AC 代码:

//迭代
class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        int maxnum = 0;
        int serielnum = 1;
        vector<int> ret;
        int pre = INT_MIN;
        stack<TreeNode*> stk;
        while(root||!stk.empty())
        {
            if(root)
            {
                stk.push(root);
                root = root->left;
            }
            else
            {
                root = stk.top();
                stk.pop();
                if(root->val==pre)
                    ++serielnum;
                else
                    serielnum=1;
                if(serielnum>maxnum)
                {
                    ret = vector<int>{root->val};
                    maxnum = serielnum;
                }
                else if(serielnum==maxnum)
                    ret.push_back(root->val);
                pre = root->val;
                root = root->right;
            }
        }
        return ret;
    }
};

//递归
void inOrder(TreeNode* root, TreeNode*& pre, int& curTimes, 
             int& maxTimes, vector<int>& res){
    if (!root) return;
    inOrder(root->left, pre, curTimes, maxTimes, res);
    if (pre)
        curTimes = (root->val == pre->val) ? curTimes + 1 : 1;
    if (curTimes == maxTimes)
        res.push_back(root->val);
    else if (curTimes > maxTimes){
        res.clear();
        res.push_back(root->val);
        maxTimes = curTimes;
    }
    pre = root;
    inOrder(root->right, pre, curTimes, maxTimes, res);
}
vector<int> findMode(TreeNode* root) {
    vector<int> res;
    if (!root) return res;
    TreeNode* pre = NULL;
    int curTimes = 1, maxTimes = 0;
    inOrder(root, pre, curTimes, maxTimes, res);
    return res;
}