前言
欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
今天是七月集训第十八天:树🔥🔥🔥
一、练习题目
二、算法思路
- 1、1339. 分裂二叉树的最大乘积:🔥🔥🔥这题是用了两次递归,第一次递归求整棵树的结点总和;第二次递归是去求每一个结点作为要被截断的边,求出最大的乘积。
三、源码剖析
// 1339. 分裂二叉树的最大乘积
class Solution {
unordered_map<TreeNode*, int> sum;
int n;
long long ans;
int dfs(TreeNode* root) {
if(root == nullptr) {
return 0;
}
int tmp = root->val;
return sum[root] = tmp + (dfs(root->left) + dfs(root->right));
}
void ndfs(TreeNode* root) {
if(root->left) {
ans = max(ans, (long long)sum[root->left] * (n - sum[root->left]));
ndfs(root->left);
}
if(root->right) {
ans = max(ans, (long long)sum[root->right] * (n - sum[root->right]));
ndfs(root->right);
}
}
public:
int maxProduct(TreeNode* root) {
dfs(root); //(1)
n = sum[root];
ans = 0;
ndfs(root); //(2)
return ans % 1000000007;
}
};
- 1、第一次的递归遍历求得结点的总和,后面要用;
- 2、第二次递归求出每个结点都作为要被删除的边的子树的乘积的最大值,并保存下来,假设要求a->b的,我们就用上面求出的总数 s u m = s u m ( a ) ∗ ( n − s u m ( a ) ) sum = sum(a) * (n - sum(a)) sum=sum(a)∗(n−sum(a))。