leetcode 1339. 分裂二叉树的最大乘积 中等

给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。

由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。

示例 1:

复制代码
输入:root = [1,2,3,4,5,6]
输出:110
解释:删除红色的边,得到 2 棵子树,和分别为 11 和 10 。它们的乘积是 110 (11*10)

示例 2:

复制代码
输入:root = [1,null,2,3,4,null,null,5,6]
输出:90
解释:移除红色的边,得到 2 棵子树,和分别是 15 和 6 。它们的乘积为 90 (15*6)

示例 3:

复制代码
输入:root = [2,3,9,10,7,8,6,5,4,11,1]
输出:1025

示例 4:

复制代码
输入:root = [1,1]
输出:1

提示:

  • 每棵树最多有 50000 个节点,且至少有 2 个节点。
  • 每个节点的值在 [1, 10000] 之间。

分析:当两个数的和为定值时,若想乘积最大,则两个数的差应当尽可能小。可以先 DFS 求出所有节点的和,再进行一次 DFS,对每个节点求出它的左子树和与右子树和,再分别检查这两个和与总结点和一半的距离,保留所有节点距离总和一般最近的值,最后求乘积即可。即 DFS 过程中先不计算乘积,最后只计算一次乘积。

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
typedef struct node
{
    struct node *left,*right;
    long long val,left_sum,right_sum;
}node;

void Free(node *p)
{
    if(p==NULL)return;
    Free(p->left);
    Free(p->right);
    free(p);
}

node *build_tree(struct TreeNode *r)
{
    if(r==NULL)return NULL;

    node *p=(node*)malloc(sizeof(node));
    p->val=r->val*1LL;
    p->left=build_tree(r->left);p->right=build_tree(r->right);

    if(p->left!=NULL)p->left_sum=p->left->val+p->left->left_sum+p->left->right_sum;
    else p->left_sum=0;
    if(p->right!=NULL)p->right_sum=p->right->val+p->right->left_sum+p->right->right_sum;
    else p->right_sum=0;

    return p;
}

long long get_ans(node *p,long long total)
{
    if(p==NULL)return 0;
    long long sum=0,sum_l=p->left_sum,sum_r=p->right_sum;

    if(sum_l*2>total)sum_l=total-sum_l;
    if(sum_r*2>total)sum_r=total-sum_r;
    sum=fmax(sum_l,sum_r);

    return fmax(sum,fmax(get_ans(p->left,total),get_ans(p->right,total)));
}

int maxProduct(struct TreeNode* root) {
    long long mod=1e9+7,sum=0,ans=0,total=0;
    node *r=build_tree(root);total=r->val+r->left_sum+r->right_sum;
    ans=get_ans(r,total);
    Free(r);
    return ans*(total-ans)%mod;
}
相关推荐
smj2302_796826521 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
_深海凉_5 小时前
LeetCode热题100-寻找两个正序数组的中位数
算法·leetcode·职场和发展
踩坑记录6 小时前
leetcode hot100 寻找两个正序数组的中位数 hard 二分查找 双指针
leetcode
superior tigre9 小时前
78 子集
算法·leetcode·深度优先·回溯
superior tigre10 小时前
739 每日温度
算法·leetcode·职场和发展
6Hzlia11 小时前
【Hot 100 刷题计划】 LeetCode 15. 三数之和 | C++ 排序+双指针
c++·算法·leetcode
北顾笙98012 小时前
day37-数据结构力扣
数据结构·算法·leetcode
6Hzlia15 小时前
【Hot 100 刷题计划】 LeetCode 189. 轮转数组 | C++ 三次反转经典魔法 (O(1) 空间)
c++·算法·leetcode
m0_6294947315 小时前
LeetCode 热题 100-----13.最大子数组和
数据结构·算法·leetcode
田梓燊15 小时前
力扣:94.二叉树的中序遍历
数据结构·算法·leetcode