二叉树:求搜索树中的众数
501.二叉搜索树中的众数给定一个有相同值的二叉搜索树(BST) , 找出 BST 中的所有众数(出现频率最高的元素) 。
假定 BST 有如下定义:
- 结点左子树中所含结点的值小于等于当前结点的值
- 结点右子树中所含结点的值大于等于当前结点的值
- 左子树和右子树都是二叉搜索树
给定 BST [1,null,2,2],
![二叉树:求搜索树中的众数](http://res.youth.cn/img-detail/b197915f5a07afd0f5c060bfc6924d93:938:234.jpg)
返回[2].
提示:如果众数超过1个 , 不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
思路这道题目呢 , 递归法我从两个维度来讲 。
首先如果不是二叉搜索树的话 , 应该怎么解题 , 是二叉搜索树 , 又应该如何解题 , 两种方式做一个比较 , 可以加深大家对二叉树的理解 。
递归法如果不是二叉搜索树如果不是二叉搜索树 , 最直观的方法一定是把这个树都遍历了 , 用map统计频率 , 把频率排个序 , 最后取前面高频的元素的集合 。
具体步骤如下:
- 这个树都遍历了 , 用map统计频率
这里采用前序遍历 , 代码如下:
// map key:元素 , value:出现频率void searchBST(TreeNode* cur, unordered_mapmap[cur->val]++; // 统计元素频率searchBST(cur->left, map);searchBST(cur->right, map);return ;}
- 把统计的出来的出现频率(即map中的value)排个序
所以要把map转化数组即vector , 再进行排序 , 当然vector里面放的也是pair
代码如下:
bool static cmp (const pair // 按照频率从大到小排序}vector> vec(map.begin(), map.end());sort(vec.begin(), vec.end(), cmp); // 给频率排个序
- 取前面高频的元素
代码如下:
result.push_back(vec[0].first);for (int i = 1; i < vec.size(); i++) {// 取最高的放到result数组中if (vec[i].second == vec[0].second) result.push_back(vec[i].first);else break;}return result;
整体C++代码如下:class Solution {private:void searchBST(TreeNode* cur, unordered_mapmap[cur->val]++; // 统计元素频率searchBST(cur->left, map);searchBST(cur->right, map);return ;}bool static cmp (const pair}public:vector findMode(TreeNode* root) {unordered_map map; // key:元素 , value:出现频率vector result;if (root == NULL) return result;searchBST(root, map);vector> vec(map.begin(), map.end());sort(vec.begin(), vec.end(), cmp); // 给频率排个序result.push_back(vec[0].first);for (int i = 1; i < vec.size(); i++) {// 取最高的放到result数组中if (vec[i].second == vec[0].second) result.push_back(vec[i].first);else break;}return result;}};
「所以如果本题没有说是二叉搜索树的话 , 那么就按照上面的思路写!」是二叉搜索树「既然是搜索树 , 它中序遍历就是有序的」 。
如图:
![二叉树:求搜索树中的众数](http://res.youth.cn/img-detail/c8206a8c3533b852383cccac72da81fc:640:515.jpg)
中序遍历代码如下:
void searchBST(TreeNode* cur) {if (cur == NULL) return ;searchBST(cur->left);// 左(处理节点)// 中searchBST(cur->right);// 右return ;}
遍历有序数组的元素出现频率 , 从头遍历 , 那么一定是相邻两个元素作比较 , 然后就把出现频率最高的元素输出就可以了 。关键是在有序数组上的话 , 好搞 , 在树上怎么搞呢?
这就考察对树的操作了 。
在二叉树:搜索树的最小绝对差 中我们就使用了pre指针和cur指针的技巧 , 这次又用上了 。
弄一个指针指向前一个节点 , 这样每次cur(当前节点)才能和pre(前一个节点)作比较 。
而且初始化的时候pre = NULL , 这样当pre为NULL时候 , 我们就知道这是比较的第一个元素 。
代码如下:
if (pre == NULL) { // 第一个节点count = 1; // 频率为1} else if (pre->val == cur->val) { // 与前一个节点数值相同count++;} else { // 与前一个节点数值不同count = 1;}pre = cur; // 更新上一个节点
此时又有问题了 , 因为要求最大频率的元素集合(注意是集合 , 不是一个元素 , 可以有多个众数) , 如果是数组上大家一般怎么办?
- 发展|我省要求互联网平台坚持依法合规经营 推动线上经济健康规范发展
- 现状|程序员现状揭秘:平均年薪20.36万,Java人才需求量最大
- 印度|拒绝华为后,印度、英国斥资数十亿求助日本
- 承受|折叠屏iPhone已开始测试?要求能承受10万次折叠,或在2年后发布
- “树标提质”提升“软实力”数字经济时代创新载体大有可为
- 区企联企协|谋求更高质量的转型发展!区企联企协与区科技局成功举办科技考察对接活动
- 品牌|为求差异化 山姆升级自有品牌Member’s Mark
- 中国|意大利制造求助中国网站,意外交部长出马见证
- 需求|需求下降!传三星可能停售高端Galaxy Note智能手机,重心转移至可折叠手机
- 高像素|加持高像素只为解析力?vivo S7丛林秘境展对样张细节的要求更严苛