直接想怎么切会绕进去,看看提示:
we know the sum of a subtree, the answer is max( (total_sum - subtree_sum) * subtree_sum) in each node.
所以很容易想到两次遍历的方法,首先计算出整个数的和sum,然后再算每个子数组和的时候,求一下最大值。注意直接算乘法数据会溢出,因此用数学知识优化一下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
typedef long long LL;
const int mod = (int)1e9+7;
class Solution {
public:
int maxProduct(TreeNode* root) {
dfs(root);
subTreeSum(root);
return (LL)(val * (sum - val))%mod;
}
LL sum = 0;
//int res = 0;
int val = 0;
void dfs(TreeNode* root){
if(root == NULL){
return;
}
sum += root -> val;
dfs(root->left);
dfs(root->right);
}
int subTreeSum(TreeNode* root){
if(root == NULL){
return 0;
}
int tmp = root -> val + subTreeSum(root->left) + subTreeSum(root->right);
if(abs(sum - 2 * tmp) < abs(sum - 2 * val)){
val = tmp;
}
//LL tmp = (val * (sum - val)) % mod;
//res = max(res, (int)tmp);å
return tmp;
}
};
一次遍历
typedef long long LL;
const int mod = (int) 1e9 + 7;
class Solution {
public:
vector<LL> sum;
int maxProduct(TreeNode* root) {
LL res;
dfs(root);
for(auto s : sum){
res = max(res, s * (sum.back() - s));
}
return (res % mod);
}
int dfs(TreeNode* root){
if(root == NULL){
return 0;
}
int val = root -> val + dfs(root->left) + dfs(root->right);
sum.push_back(val);
return val;
}
};