[LeetCode] 508. Most Frequent Subtree Sum 出现频率最高的子树和
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.
Examples 1
Input:
5
/ \
2 -3
return [2, -3, 4], since all the values happen only once, return all of them in any order.
Examples 2
Input:
5
/ \
2 -5
return [2], since 2 happens twice, however -5 only occur once.
Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.
这道题给了我们一个二叉树,让我们求出现频率最高的子树之和,求树的结点和并不是很难,就是遍历所有结点累加起来即可。那么这道题的暴力解法就是遍历每个结点,对于每个结点都看作子树的根结点,然后再遍历子树所有结点求和,这样也许可以通过 OJ,但是绝对不是最好的方法。我们想下子树有何特点,必须是要有叶结点,单独的一个叶结点也可以当作是子树,那么子树是从下往上构建的,这种特点很适合使用后序遍历,我们使用一个 HashMap 来建立子树和跟其出现频率的映射,用一个变量 cnt 来记录当前最多的次数,递归函数返回的是以当前结点为根结点的子树结点值之和,然后在递归函数中,我们先对当前结点的左右子结点调用递归函数,然后加上当前结点值,然后更新对应的 HashMap 中的值,然后看此时 HashMap 中的值是否大于等于 cnt,大于的话首先要清空 res,等于的话不用,然后将 sum 值加入结果 res 中即可,参见代码如下:
解法一:
class Solution {
public:
vector<int> findFrequentTreeSum(TreeNode* root) {
vector<int> res;
unordered_map<int, int> m;
int cnt = ;
postorder(root, m, cnt, res);
return res;
}
int postorder(TreeNode* node, unordered_map<int, int>& m, int& cnt, vector<int>& res) {
if (!node) return ;
int left = postorder(node->left, m, cnt, res);
int right = postorder(node->right, m, cnt, res);
int sum = left + right + node->val;
++m[sum];
if (m[sum] >= cnt) {
if (m[sum] > cnt) res.clear();
res.push_back(sum);
cnt = m[sum];
}
return sum;
}
};
下面这种解法跟上面的基本一样,就是没有在递归函数中更新结果 res,更是利用 cnt,最后再更新 res,这样做能略微高效一些,参见代码如下:
解法二:
class Solution {
public:
vector<int> findFrequentTreeSum(TreeNode* root) {
vector<int> res;
unordered_map<int, int> m;
int cnt = ;
postorder(root, m, cnt);
for (auto a : m) {
if (a.second == cnt) res.push_back(a.first);
}
return res;
}
int postorder(TreeNode* node, unordered_map<int, int>& m, int& cnt) {
if (!node) return ;
int left = postorder(node->left, m, cnt);
int right = postorder(node->right, m, cnt);
int sum = left + right + node->val;
cnt = max(cnt, ++m[sum]);
return sum;
}
};
开始我还在想能不能利用后序遍历的迭代形式来解,后来想了半天发现不太容易实现,因为博主无法想出有效的机制来保存左子树结点之和,而计算完对应的右子树结点之和后要用到对应的左子树结点之和,才能继续往上算。可能博主不够 smart,有大神如果知道如何用迭代的形式来解,请一定要留言告知博主啊,多谢啦~
Github 同步地址:
https://github.com/grandyang/leetcode/issues/508
类似题目:
参考资料:
https://leetcode.com/problems/most-frequent-subtree-sum/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 508. Most Frequent Subtree Sum 出现频率最高的子树和的更多相关文章
- 508 Most Frequent Subtree Sum 出现频率最高的子树和
详见:https://leetcode.com/problems/most-frequent-subtree-sum/description/ C++: /** * Definition for a ...
- [LeetCode] Most Frequent Subtree Sum 出现频率最高的子树和
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...
- 508. Most Frequent Subtree Sum 最频繁的子树和
[抄题]: Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum ...
- [leetcode]508. Most Frequent Subtree Sum二叉树中出现最多的值
遍历二叉树,用map记录sum出现的次数,每一个新的节点都统计一次. 遍历完就统计map中出现最多的sum Map<Integer,Integer> map = new HashMap&l ...
- 【LeetCode】508. Most Frequent Subtree Sum 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 508. Most Frequent Subtree Sum
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...
- LeetCode - Most Frequent Subtree Sum
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...
- [leetcode-508-Most Frequent Subtree Sum]
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...
- [Swift]LeetCode508. 出现次数最多的子树元素和 | Most Frequent Subtree Sum
Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...
随机推荐
- 自动化API之一 自动生成Mysql数据库的微服务API
本文演示如何利用Uniconnector平台,自动生成Mysql数据库的API,节约开发人员编写后台API的时间.使用生成API的前提是开发者有 自己的数据库,有数据库的管理权限,并能通过外网 ...
- 小小见解之python循环依赖
a.py from b import b print '---------this is module a.py----------' def a(): print "hello, a&qu ...
- SpringDataRedis简单入门介绍
1:问题引入 在实际开发中,开发的每一个项目,每天都有大量的人访问,对数据库造成很大的访问压力,甚至是瘫痪.那如何解决呢?我们通常的做法有两种:一种是数据缓存.一种是网页静态化.我们今天讨论第一种解决 ...
- C# SmtpClient 发邮件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Python 高级特性:切片、迭代、列表生成式、生成器
切片(发现了一些新操作) 参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017269965565856 间隔取元素(可以取负数,负数就 ...
- HTML input属性详谈
value属性 value属性指定输入字段的初始值: <form> 名字:<br> <input type="text" name="you ...
- QT4.8.7和VS2010环境搭建及使用
(一)环境搭建 首先下载QT4.8.7的安装包.QT Addin 1.11插件和VS2010安装包.第一步:安装好VS2010第二步:安装QT4.8.7(qt-opensource-windows-x ...
- i春秋暑期训练营丨渗透测试工程师开课啦
每个人的夏天 都有专属的解锁方式 或来一次难忘的旅行 或躺在家里吹着空调吃西瓜 又或者是和小伙伴参加暑期训练营 i春秋暑期渗透测试工程师 报名通道已全部开启 为了保证课程质量,采取小班教学,每班仅限3 ...
- A dependency may only have one source
在使用Flutter的时候添加依赖报错了 Error on line 21, column 5 of pubspec.yaml: A dependency may only have one sour ...
- vuejs的导航栏固定
https://blog.csdn.net/wang1006008051/article/details/78003974 博主文章,超级详细,上面传送们 不过博主的导航栏跳动比较明显,我自己做了修复 ...