https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/

难度:简单


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

假定 BST 有如下定义:

  • 结点左子树中所含结点的值小于等于当前结点的值

  • 结点右子树中所含结点的值大于等于当前结点的值

  • 左子树和右子树都是二叉搜索树

例如:

  给定 BST [1,null,2,2],

   1\2/2

  返回 [2]

提示:如果众数超过1个,不需考虑输出顺序

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


解法1:中序遍历

  对于一棵二叉搜索树,若对其进行中序遍历并在遍历过程中顺序记录节点值,那么记录的值会是一个单调递增序列(在本题中是单调不减序列)。

  这样的话,若要求众数,我们可以先对其进行中序遍历,众数在序列中的位置一定是连续的,如 [1, 2, 2, 2, 3]。这样,我们对这个序列进行遍历并计数,就能够得到它的众数。

  不过,为了避免使用额外空间,我们可以在遍历过程中就求出众数,具体做法是维护一个 max ,表示当前所遇到的最多的连续数字的个数,然后在遍历过程中累计每个数字出现的次数,若比 max 大,则使用当前数字覆盖结果数组,并更新 max 值。

  在中序遍历完成之后,我们还需要最后进行一次众数判断,因为最后的连续数字不会在遍历过程中判断是否是众数。

JS 代码:

var findMode = function(root) {let res = [];if (!root) {return res;}let n;let count = 0;let max = -1;const dfs = (node) => {if (!node) {return;}dfs(node.left);if (n === undefined) {n = node.val;count = 1;} else if (n === node.val) {count++;} else { // 遇到新的数字if (count > max) {max = count;res = [n];} else if (count === max) {res.push(n);}n = node.val;count = 1;}    dfs(node.right);};dfs(root);if (count > max) {max = count;res = [n];} else if (count === max) {res.push(n);}return res;
};

C 版本:

int max;
int count;
int cur;void dfs(struct TreeNode* root, int* res, int* returnSize) {if (!root) {return;}dfs(root->left, res, returnSize);if (count == -1) {cur = root->val;count = 1;} else if (cur == root->val) {count++;} else {if (max < count) {max = count;*returnSize = 0;res[(*returnSize)++] = cur;} else if (max == count) {res[(*returnSize)++] = cur;}cur = root->val;count = 1;}dfs(root->right, res, returnSize);
}int* findMode(struct TreeNode* root, int* returnSize){*returnSize = 0;int *res = malloc(sizeof(int) * 4001);count = -1;max = -1;if (!root) {return res;}dfs(root, res, returnSize);if (max < count) {max = count;*returnSize = 0;res[(*returnSize)++] = cur;} else if (max == count) {res[(*returnSize)++] = cur;}return res;
}

解法2:Morris 算法

  所有能使用中序遍历解决的问题都能使用 Morris 算法来优化其空间复杂度。

  Morris 算法详情可看

  在使用 Morris 算法时最重要的是要把握好节点遍历的时机。

var findMode = function(root) {let res = [];if (!root) {return res;}let n;let count = 0;let max = -1;let pre;const check = () => {if (max < count) {max = count;res = [n];} else if (max === count) {res.push(n);}};while (root) {if (root.left) {pre = root.left;while (pre.right && pre.right !== root) {pre = pre.right;}if (!pre.right) {pre.right = root;root = root.left;} else { // 此时是刚从左孩子节点返回之后,往右孩子遍历if (n === undefined) {n = root.val;count = 1;} else if (n === root.val) {count++;} else {check();n = root.val;count = 1;}pre.right = null;root = root.right;}} else {// 节点此时可能是借助前面设置的空闲指针返回父节点,也可能是从父节点到右节点遍历的过程if (n === undefined) {n = root.val;count = 1;} else if (n === root.val) {count++;} else {check();n = root.val;count = 1;}root = root.right;}}check();return res;
};

LeetCode 501. 二叉搜索树中的众数相关推荐

  1. LeetCode 501. 二叉搜索树中的众数(中序遍历)

    文章目录 1. 题目 2. 中序遍历 1. 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等 ...

  2. 74. Leetcode 501. 二叉搜索树中的众数 (二叉搜索树-中序遍历类)

    给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如下定义:结 ...

  3. leetcode 501. 二叉搜索树中的众数(Java版)

    题目 https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/ 题解 中序遍历二叉搜索树,可以得到一个有序序列. 遍历这个有序 ...

  4. LeetCode 501二叉搜索树中的众数-简单

    给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等于当前结点的值 结点右子树中所含结点的值大于等于当 ...

  5. leetcode 501. 二叉搜索树中的众数 思考分析

    目录 题目 1.不考虑BTS性质,直接寻找众数集合(利用map) 2.考虑BTS的中序遍历结果性质 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假 ...

  6. [力扣] 501. 二叉搜索树中的众数

    501 二叉搜索树中的众数 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 例如: 给定 BST [1,null,2,2], 返回[2]. 提示:如果众数超 ...

  7. Suzy找到实习了吗 Day 21 | 二叉树进行中:530. 二叉搜索树的最小绝对差,501. 二叉搜索树中的众数,236. 二叉树的最近公共祖先

    530. 二叉搜索树的最小绝对差 题目 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 .差值是一个正数,其数值等于两值之差的绝对值. solution # Defi ...

  8. leetcode系列-501. 二叉搜索树中的众数

    题目描述:给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如 ...

  9. 力扣501. 二叉搜索树中的众数(JavaScript)

    //使用双指针记录同一值的出现次数 var findMode = function(root) {let p=rootlet count=0 //次数let max=1let arr=[]const ...

最新文章

  1. 51nod 1179 最大的最大公约数 (打表计数法)
  2. hibernate 7大主键生成策略详解与对象状态
  3. 修改Linux字体出现乱码
  4. redis api-list
  5. 在ASP.NET 3.5中使用新的ListView控件1
  6. python实现背景抠除_利用Python代码实现一键抠背景功能
  7. 解决Idea中Cannot resolve plugin org.apache.maven.plugins:maven-clean-plugin:3.1.0配置问题
  8. 发生无法识别的错误_车牌识别系统的核心部件抓拍摄像机怎么安装?
  9. c++基础:继承与组合!
  10. WPF 中依赖属性的继承(Inherits)
  11. oracle c# 插入中文乱码,C#写入Oracle 中文乱码问题
  12. 机器学习面试题60~100
  13. 通过Python获取维基百科中概念词条的维基信息
  14. CARLA 笔记(05)— Actors and blueprints(创建和修改 Blueprint、生成 Spawning、使用 Handling、销毁 Destruction)
  15. python科研向数据处理篇——python-pptx批量向PPT中插入图片
  16. MMPlayer同步文件到手机应用中的方法
  17. [转]倾斜摄影单体化实现方案
  18. Springboot Could not resolve placeholder ‘spring.data.mongodb.database’ in value “${spring.data.mong
  19. 【ModuleNotFoundError 与 ImportError】之 most likely due to a circular import
  20. 托业考试常遇到的科学论文词汇汇总

热门文章

  1. 容器环境红队手法总结
  2. 37张图详解MAC地址、以太网、二层转发、VLAN
  3. 工资倒挂也刺激不了已是咸鱼的你
  4. 15张图来了解【树】,面试再也不怕被刷了
  5. 美团点评基于 Flink 的实时数仓建设实践
  6. 你居然还不知道Mysql存储引擎InnoDB分为内存架构、磁盘架构?
  7. 毕业五年,几个月入百万阿里系大神的公众号!
  8. 针对脑出血识别的AI匹配准确性
  9. 想高效办公,有什么好的多端协作平台推荐吗?
  10. Leangoo用户设置在哪里?