leetcode笔记之[501. 二叉搜索树中的众数]

37 阅读1分钟

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

一、题目描述:

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

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

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

假定 BST 满足如下定义:

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

示例 1:

image.png

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

示例 2:

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

提示:

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

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

二、思路分析:

二叉搜索树的中序遍历是一个递增数列,而众数是出现最多的数字,我们用一个pre保存之前遍历的那个节点,如果后面一个节点跟它的值相同,证明这个数出现的次数应该加1, 当加到跟maxTimes相同的时候,证明这个是众数,可以加入结果数组,如果大于maxTimes, 证明我们前面统计的结果数组都无效了,应该清除数组,重新进行累计。

三、AC 代码:

var findMode = function(root) {
  var pre = null
  var currentTimes = 1
  var maxTimes = 0
  var res = []
  function inOrder(root) {
    if (!root) return
    // 遍历左结点
    inOrder(root.left)
    if (pre) {
      currentTimes = (root.val === pre.val) ? (currentTimes + 1) : 1
    }
    if (currentTimes === maxTimes) {
      res.push(root.val)
    } else if (currentTimes > maxTimes) {
      res.splice(0, res.length)
      res.push(root.val)
      maxTimes = currentTimes
    }
    pre = root
    // 遍历右节点
    inOrder(root.right)
  }

  if (!root) return res
  inOrder(root)
  return res
};

范文参考

7-5;候选人。NC73 数组中出现次数超过一半的数字 - 二叉搜索树中的众数 - 力扣(LeetCode)