鉴于树的根,您被要求找到最频繁的子树总和。 节点的子树总和定义为以该节点(包括节点本身)为根的子树形成的所有节点值之和。 那么什么是最频繁的子树总和值? 如果存在平局,则以任意顺序返回所有具有最高频率的值。
例子1输入:
5 / \ 2 -3返回[2,-3,4],因为所有的值只发生一次,以任意顺序返回它们全部。
例2
输入:
5 / \ 2 -5返回[2],因为2发生两次,但-5只发生一次。
注意:您可以假定任何子树中的值总和在32位有符号整数的范围内。
思路:
采用后序遍历的方法,在遍历到当前节点时已经得到左右子节点的累加和,和自己节点的值累加,然后加到hashmap<int,int>中,hashmap中的key是节点的累加和,value是累加和对应的次数。并定义一个变量max_保存整个hashmap中value的最大值。在后序遍历完整棵树后,寻找value值等于max_的key放到结果集res中即可。
代码如下:
void findFrequentTreeSumCore(TreeNode* root, unordered_map<int, int> &m,int &cnt,int &max_) {
if (!root) {
return;
}
int cnt_left = 0;
int cnt_right = 0;
findFrequentTreeSumCore(root->left, m, cnt_left,max_);
findFrequentTreeSumCore(root->right, m, cnt_right,max_);
cnt += root->val + cnt_left + cnt_right;
if (m.find(cnt)!=m.end()) {
m[cnt]++;
}
else {
m[cnt] = 1;
}
max_ = max(max_, m[cnt]);
}
vector<int> findFrequentTreeSum(TreeNode* root) {
vector<int> res;
if (!root) {
res;
}
unordered_map<int, int> m;
int cnt=0;
int max_ = 0;
findFrequentTreeSumCore(root, m, cnt, max_);
unordered_map<int, int>::iterator it;
it = m.begin();
while (it != m.end()) {
if (it->second == max_) {
res.push_back(it->first);
}
it++;
}
return res;
}