[LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数
Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST.
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than or equal to the node's key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
- Both the left and right subtrees must also be binary search trees.
For example:
Given BST [1,null,2,2]
,
1
\
2
/
2
return [2]
.
Note: If a tree has more than one mode, you can return them in any order.
Follow up: Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).
这道题让我们求二分搜索树中的众数,这里定义的二分搜索树中左根右结点之间的关系是小于等于的,有些题目中是严格小于的,所以一定要看清题目要求。所谓的众数就是出现最多次的数字,可以有多个,那么这道题比较直接点思路就是利用一个哈希表来记录数字和其出现次数之前的映射,然后维护一个变量mx来记录当前最多的次数值,这样在遍历完树之后,根据这个mx值就能把对应的元素找出来。那么用这种方法的话就不需要用到二分搜索树的性质了,随意一种遍历方式都可以,下面我们来看递归的中序遍历的解法如下:
解法一:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
vector<int> res;
int mx = ;
unordered_map<int, int> m;
inorder(root, m, mx);
for (auto a : m) {
if (a.second == mx) {
res.push_back(a.first);
}
}
return res;
}
void inorder(TreeNode* node, unordered_map<int, int>& m, int& mx) {
if (!node) return;
inorder(node->left, m, mx);
mx = max(mx, ++m[node->val]);
inorder(node->right, m, mx);
}
};
下面这种解法是上面方法的迭代形式,也是用的中序遍历的方法,有兴趣的童鞋可以实现其他的遍历方法:
解法二:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
if (!root) return {};
vector<int> res;
TreeNode *p = root;
stack<TreeNode*> s;
unordered_map<int, int> m;
int mx = ;
while (!s.empty() || p) {
while (p) {
s.push(p);
p = p->left;
}
p = s.top(); s.pop();
mx = max(mx, ++m[p->val]);
p = p->right;
}
for (auto a : m) {
if (a.second == mx) {
res.push_back(a.first);
}
}
return res;
}
};
题目中的follow up说了让我们不用除了递归中的隐含栈之外的额外空间,那么我们就不能用哈希表了,不过这也不难,由于是二分搜索树,那么我们中序遍历出来的结果就是有序的,这样我们只要比较前后两个元素是否相等,就等统计出现某个元素出现的次数,因为相同的元素肯定是都在一起的。我们需要一个结点变量pre来记录上一个遍历到的结点,然后mx还是记录最大的次数,cnt来计数当前元素出现的个数,我们在中序遍历的时候,如果pre不为空,说明当前不是第一个结点,我们和之前一个结点值比较,如果相等,cnt自增1,如果不等,cnt重置1。如果此时cnt大于了mx,那么我们清空结果res,并把当前结点值加入结果res,如果cnt等于mx,那我们直接将当前结点值加入结果res,然后mx赋值为cnt。最后我们要把pre更新为当前结点,参见代码如下:
解法三:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
vector<int> res;
int mx = , cnt = ;
TreeNode *pre = NULL;
inorder(root, pre, cnt, mx, res);
return res;
}
void inorder(TreeNode* node, TreeNode*& pre, int& cnt, int& mx, vector<int>& res) {
if (!node) return;
inorder(node->left, pre, cnt, mx, res);
if (pre) {
cnt = (node->val == pre->val) ? cnt + : ;
}
if (cnt >= mx) {
if (cnt > mx) res.clear();
res.push_back(node->val);
mx = cnt;
}
pre = node;
inorder(node->right, pre, cnt, mx, res);
}
};
下面这种方法是上面解法的迭代写法,思路基本相同,可以参考上面的讲解,参见代码如下:
解法四:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
if (!root) return {};
vector<int> res;
TreeNode *p = root, *pre = NULL;
stack<TreeNode*> s;
int mx = , cnt = ;;
while (!s.empty() || p) {
while (p) {
s.push(p);
p = p->left;
}
p = s.top(); s.pop();
if (pre) {
cnt = (p->val == pre->val) ? cnt + : ;
}
if (cnt >= mx) {
if (cnt > mx) res.clear();
res.push_back(p->val);
mx = cnt;
}
pre = p;
p = p->right;
}
return res;
}
};
类似题目:
参考资料:
https://discuss.leetcode.com/topic/77335/proper-o-1-space
https://discuss.leetcode.com/topic/77080/c-dfs-time-o-n-space-o-n
https://discuss.leetcode.com/topic/77077/ugly-but-straight-forward-java-solution
https://discuss.leetcode.com/topic/77330/java-4ms-beats-100-extra-o-1-solution-no-map
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数的更多相关文章
- 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)
[LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...
- 【一天一道LeetCode】#99. Recover Binary Search Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Two ele ...
- LeetCode Find Mode in Binary Search Tree
原题链接在这里:https://leetcode.com/problems/find-mode-in-binary-search-tree/#/description 题目: Given a bina ...
- 【LeetCode】 99. Recover Binary Search Tree [Hard] [Morris Traversal] [Tree]
Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...
- 【LeetCode】1008. Construct Binary Search Tree from Preorder Traversal 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- 【LeetCode OJ】Recover Binary Search Tree
Problem Link: https://oj.leetcode.com/problems/recover-binary-search-tree/ We know that the inorder ...
- 【一天一道LeetCode】#98. Validate Binary Search Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
随机推荐
- [LTR] 信息检索评价指标(RP/MAP/DCG/NDCG/RR/ERR)
一.RP R(recall)表示召回率.查全率,指查询返回结果中相关文档占所有相关文档的比例:P(precision)表示准确率.精度,指查询返回结果中相关文档占所有查询结果文档的比例: 则 PR 曲 ...
- [BZOJ 1040][ZJOI2008]骑士
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5403 Solved: 2060[Submit][Status ...
- (译文)学习ES6非常棒的特性-深入研究var, let and const
Var var firstVar; //firstVar被声明,它的默认值是undefined var secondVar = 2; //secondVar被声明,被赋值2 先看一个例子: var i ...
- (译文)开始学习Vue——构建你的第一个Vue应用
我们要构建如下组件:(最终代码在这里:https://codesandbox.io/s/38k1y8x375) 开始 Vue是支持单文件组件的,但是我们不准备这么做.你也可以构建一个全局的组件,通过V ...
- 关于from nltk.book import * 报错解决方法
import nltk nltk.download() 在使用上面命令安装了nltk库并运行下载后,再输入from nltk.book import * 往往会出现这样的错误提示: 出现这种错误往往是 ...
- io多路复用(二)
服务端 import socket sk1 = socket.socket() sk1.bind(('127.0.0.1',8001,)) sk1.listen() inputs = [sk1,] i ...
- MySQL搭建主从数据库 实现读写分离
首先声明,实际生产中,网站为了提高用户体验,性能等,将数据库实现读写分离是有必要的,我们让主数据库去写入数据,然后当用户查询的时候,然后在从数据库读取数据,故能减轻数据库的压力,实现良好的用户体验! ...
- 【bug清除】新Surface Pro使用OneNote出现毛刺现象的解决方案
在写字的时候,左手触摸Surface的金属外壳背面,大概两个手指指肚大小.问题亲测可以得到解决. 推测是设备使用时接地没有做好,导致电磁笔出现偏移.问题初步锁定在新笔的倾斜感应上. 参考资料: htt ...
- 使用 HttpClient 请求 Web Api
1.获取 post 请求 body 内容 [HttpPost] public string GetId() { //如果方法参数里面有 [FromBody],则需要重新调整内容指针,再进行读取. // ...
- SpringBoot应用的集成测试
一.概念和定义 进行软件开发的时候,我们会写很多代码,不过,再过六个月(甚至一年以上)你知道自己的代码怎么运作么?通过测试(单元测试.集成测试.接口测试)可以保证系统的可维护性,当我们修改了某些代码时 ...