返回
508. 出现次数最多的子树元素和的多种写法
后端
2023-10-10 06:23:06
- 出现次数最多的子树元素和
给出二叉树的根节点 root
,返回 root
的每个结点的子树元素和的最大值。
示例:
输入:[1,2,3]
输出:[6,9,5]
输入:[5,2,-3]
输出:[10,5,2]
提示:
- 给定的树中有
1
到1000
个结点。 - 每个结点的值介于
-1000
到1000
之间。
链接: https://leetcode-cn.com/problems/most-frequent-subtree-sum/
1. 暴力求解
暴力求解法是计算每个子树的元素和,然后将这些元素和存储在一个列表中。最后,我们找出列表中出现次数最多的元素和,并将其作为结果返回。
Python 实现:
def findFrequentTreeSum(root):
# 计算每个子树的元素和
def dfs(root):
if not root:
return 0
left = dfs(root.left)
right = dfs(root.right)
# 返回子树的元素和
return root.val + left + right
# 将子树的元素和存储在列表中
sums = []
def postorder(root):
if not root:
return
postorder(root.left)
postorder(root.right)
# 将子树的元素和添加到列表中
sums.append(dfs(root))
# 计算出现次数最多的元素和
postorder(root)
counts = collections.Counter(sums)
max_count = max(counts.values())
return [sum for sum, count in counts.items() if count == max_count]
Java 实现:
class Solution {
private Map<Integer, Integer> sumCountMap;
private int maxCount;
public int[] findFrequentTreeSum(TreeNode root) {
sumCountMap = new HashMap<>();
maxCount = 0;
postorder(root);
List<Integer> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : sumCountMap.entrySet()) {
if (entry.getValue() == maxCount) {
result.add(entry.getKey());
}
}
return result.stream().mapToInt(i -> i).toArray();
}
private int postorder(TreeNode root) {
if (root == null) {
return 0;
}
int leftSum = postorder(root.left);
int rightSum = postorder(root.right);
int sum = leftSum + rightSum + root.val;
int count = sumCountMap.getOrDefault(sum, 0) + 1;
sumCountMap.put(sum, count);
maxCount = Math.max(maxCount, count);
return sum;
}
}
C++ 实现:
class Solution {
private:
unordered_map<int, int> sumCountMap;
int maxCount;
public:
vector<int> findFrequentTreeSum(TreeNode* root) {
sumCountMap.clear();
maxCount = 0;
postorder(root);
vector<int> result;
for (auto& entry : sumCountMap) {
if (entry.second == maxCount) {
result.push_back(entry.first);
}
}
return result;
}
private:
int postorder(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int leftSum = postorder(root->left);
int rightSum = postorder(root->right);
int sum = leftSum + rightSum + root->val;
int count = sumCountMap[sum] + 1;
sumCountMap[sum] = count;
maxCount = max(maxCount, count);
return sum;
}
};
2. 使用深度优先搜索的优化解法
使用深度优先搜索的优化解法可以避免重复计算子树的元素和。在深度优先搜索过程中,我们维护一个字典来存储每个子树的元素和及其出现的次数。当我们访问一个子树时,我们首先检查字典中是否已经存在该子树的元素和。如果存在,我们直接从字典中获取出现的次数并更新最大出现的次数。如果不存在,我们计算子树的元素和,将它添加到字典中,并更新最大出现的次数。
Python 实现:
def findFrequentTreeSum(root):
# 计算每个子树的元素和
def dfs(root):
if not root:
return 0
left = dfs(root.left)
right = dfs(root.right)
# 返回子树的元素和
return root.val + left + right
# 存储子树的元素和及其出现的次数
sums = {}
# 最大出现的次数
max_count = 0
def postorder(root):
if not root:
return
postorder(root.left)
postorder(root.right)
# 计算子树的元素和
sum = dfs(root)
# 更新出现的次数和最大出现的次数
sums[sum] = sums.get(sum, 0) + 1
max_count = max(max_count, sums[sum])
postorder(root)
# 返回出现次数最多的元素和
return [sum for sum, count in sums.items() if count == max_count]
Java 实现:
class Solution {
private Map<Integer, Integer> sumCountMap;
private int maxCount;
public int[] findFrequentTreeSum(TreeNode root) {
sumCountMap = new HashMap<>();
maxCount = 0;
postorder(root);
List<Integer> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : sumCountMap.entrySet()) {
if (entry.getValue() == maxCount) {
result.add(entry.getKey());
}
}
return result.stream().mapToInt(i -> i).toArray();
}
private int postorder(TreeNode root) {
if (root == null) {
return 0;
}
int leftSum = postorder(root.left);
int rightSum = postorder(root.right);
int sum = leftSum + rightSum + root.val;
int count = sumCountMap.getOrDefault(sum, 0) + 1;
sumCountMap.put(sum, count);
maxCount = Math.max(maxCount, count);
return sum;
}
}
C++ 实现:
class Solution {
private:
unordered_map<int, int> sumCountMap;
int maxCount;
public:
vector<int> findFrequentTreeSum(TreeNode* root) {
sumCountMap.clear();
maxCount = 0;
postorder(root);
vector<int> result;
for (auto& entry : sumCountMap) {
if (entry.second == maxCount) {
result.push_back(entry.first);
}
}
return result;
}
private:
int postorder(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int leftSum = postorder(root->left);
int rightSum = postorder(root->right);
int sum = leftSum + rightSum + root->val;
int count = sumCountMap[sum] + 1;