501. 二叉搜索树中的众数(BST)


501. 二叉搜索树中的众数

题目

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

假定 BST 有如下定义:

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

在这里插入图片描述
提示: 如果众数超过1个,不需考虑输出顺序

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

解题思路

这题第一反应是直接遍历这个树,把元素出现的次数存入到一个HashMap中。但是这是一颗二叉搜索树,如果直接用HashMap效率太低了,可以考虑二叉搜索树的特性。

我们用中序遍历,比如一次中序遍历后的结果为{0,0,1,2,5,6,6}。我们可以发现,只要是一个数出现多次,那么它必是连续的。

①所以考虑用一个base,来存放当前元素,当下一次遍历的时候,我们只要拿即将遍历的元root.val和base比较

②如果相等,证明它们是同一个元素,这样的话count++;证明这个元素出现的次数加一。

③如果不等,那么更新base为root.val,并且重置count=1;这样就是一个新的元素,目前出现次数为1.

④经过上面两步后,我们再用一个MaxCount来存放之前遍历过的所有元素其中 出现次数最多的那个次数(有点绕口,简单来说就是存放的是到目前为止“出现最多的次数”注意!存放的是次数而不是元素)。

⑤那当前元素的出现次数count和maxCount比较。

⑥维护一个List 名叫answer,来存放出现次数最多的元素

⑦如果等于maxcount,证明它的出现次数和maxcount相等,即该元素出现次数也是最多的。就把root.val加入到answer中去。

⑧如果大于maxCount,那么证明出现了新的最大次数,我们更新maxcount=count;并且清空原来的answer数组,再把现在的root.val–也即是出现次数最多的那个元素存放到answer中。

⑨所有递归完成后,只要answer存放的就是答案了,但是题目要求int[],我们再在主函数中把answer转成int[]就可以了

代码

class Solution {
    List<Integer> answer = new ArrayList<Integer>();
    int base, count, maxCount;//初始值都为0
    /*
    base:记录当前的数字
    count: 记录当前数字重复的次数
    maxCount: 维护已经扫描过的数当中出现最多的那个数字的出现次数
    answer: 记录出现次数最多的元素(会经常更新)。

    */

    public int[] findMode(TreeNode root) {
        figureout(root);//这个方法执行完以后answer存放的就是出现次数最多的  哪些元素

        int[] res=new int[answer.size()];
        for(int i=0;i<answer.size();i++){
            res[i]=answer.get(i);
        }

        return res;
    }


    public void figureout(TreeNode root){
        if(root==null){
            return ;
        }
        figureout(root.left);

        if(root.val==base){//如果下一个元素和base相等则count+1
            count++;
        }else{//不相等就更新base,然后把count恢复为1
            base=root.val;
            count=1;
        }

        if(count==maxCount){//如果该元素的出现次数  和maxcount相等,就把该元素放入anser中
            answer.add(root.val);
        }else if(count>maxCount){//当前元素的出现次数大于MAXcount ,则count变成最大次数
            maxCount= count;
            answer.clear();//清空原来的集合,因为有更大的次数了,answer中只存放最大次数的元素,原来的已经不是最大的,所以要清空。
            answer.add(root.val);//把新的“出现次数最多”的元素加入到anser中,以保证anser中总是存放的目前 “出现次数最多的”  数字

        }

        figureout(root.right);
    }
}

文章作者: fFee-ops
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 fFee-ops !
评论
  目录