力扣【二叉树专题】501. 二叉搜索树中的众数

108 阅读2分钟

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

题目链接

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

题目描述

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

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

假定 BST 满足如下定义:

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

测试用例

示例 1:

image.png

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

限制

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

题目分析

由题可知,root 是一颗搜索二叉树,且他的节点包含有重复值。题目需要我们找出,这个树中,重复次数最多的节点,请注意题目的措辞,所有的 众数。因此,我们还需要考虑,有并列重复次数最多的元素。

如果不考虑搜索二叉树的特性,我们直接对树进行任意方式的遍历(如前序、中序等),再通过一个 map 辅助记录下,出现的元素,以及重复的次数

最后,对 mapkeys 按照出现的次数降序排列,然后,我们仅仅需要比对 keys 的前面数个元素,只要他们出现的次数与 keys[0] 出现的次数一致,就记录到待返回的数组即可

代码实现

完整的代码实现如下

    var findMode = function (root) {
        let obj = {};
        trave(root);
        let keys = Object.keys(obj).sort((a, b) => obj[b] - obj[a]);
        let arr = [keys[0]];
        for (let i = 1; i < keys.length && obj[keys[i]] == obj[keys[i - 1]]; i++) {
            arr.push(keys[i]);
        }
        return arr;
        function trave(node) {
            if (node == null) return;
            let val = node.val;
            obj[val] = (obj[val] || 0) + 1
            trave(node.left);
            trave(node.right);
        }
    }

image.png