LeetCode 501. 二叉搜索树中的众数
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. 二叉搜索树中的众数相关推荐
- LeetCode 501. 二叉搜索树中的众数(中序遍历)
文章目录 1. 题目 2. 中序遍历 1. 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等 ...
- 74. Leetcode 501. 二叉搜索树中的众数 (二叉搜索树-中序遍历类)
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如下定义:结 ...
- leetcode 501. 二叉搜索树中的众数(Java版)
题目 https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/ 题解 中序遍历二叉搜索树,可以得到一个有序序列. 遍历这个有序 ...
- LeetCode 501二叉搜索树中的众数-简单
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等于当前结点的值 结点右子树中所含结点的值大于等于当 ...
- leetcode 501. 二叉搜索树中的众数 思考分析
目录 题目 1.不考虑BTS性质,直接寻找众数集合(利用map) 2.考虑BTS的中序遍历结果性质 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假 ...
- [力扣] 501. 二叉搜索树中的众数
501 二叉搜索树中的众数 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 例如: 给定 BST [1,null,2,2], 返回[2]. 提示:如果众数超 ...
- Suzy找到实习了吗 Day 21 | 二叉树进行中:530. 二叉搜索树的最小绝对差,501. 二叉搜索树中的众数,236. 二叉树的最近公共祖先
530. 二叉搜索树的最小绝对差 题目 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 .差值是一个正数,其数值等于两值之差的绝对值. solution # Defi ...
- leetcode系列-501. 二叉搜索树中的众数
题目描述:给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如 ...
- 力扣501. 二叉搜索树中的众数(JavaScript)
//使用双指针记录同一值的出现次数 var findMode = function(root) {let p=rootlet count=0 //次数let max=1let arr=[]const ...
最新文章
- 51nod 1179 最大的最大公约数 (打表计数法)
- hibernate 7大主键生成策略详解与对象状态
- 修改Linux字体出现乱码
- redis api-list
- 在ASP.NET 3.5中使用新的ListView控件1
- python实现背景抠除_利用Python代码实现一键抠背景功能
- 解决Idea中Cannot resolve plugin org.apache.maven.plugins:maven-clean-plugin:3.1.0配置问题
- 发生无法识别的错误_车牌识别系统的核心部件抓拍摄像机怎么安装?
- c++基础:继承与组合!
- WPF 中依赖属性的继承(Inherits)
- oracle c# 插入中文乱码,C#写入Oracle 中文乱码问题
- 机器学习面试题60~100
- 通过Python获取维基百科中概念词条的维基信息
- CARLA 笔记(05)— Actors and blueprints(创建和修改 Blueprint、生成 Spawning、使用 Handling、销毁 Destruction)
- python科研向数据处理篇——python-pptx批量向PPT中插入图片
- MMPlayer同步文件到手机应用中的方法
- [转]倾斜摄影单体化实现方案
- Springboot Could not resolve placeholder ‘spring.data.mongodb.database’ in value “${spring.data.mong
- 【ModuleNotFoundError 与 ImportError】之 most likely due to a circular import
- 托业考试常遇到的科学论文词汇汇总