题目18: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]之间。
思路分析
两棵树的乘积什么情况下最大?
分隔后的两棵树的和的之差最小,即尽量分隔成和相近的两棵树,这个时候乘积是最大的。
- 求出整棵树的和
- 找出分隔后两课之和差值最小时,两棵树的和分别是多少
程序代码
方法一:
// https://leetcode.cn/problems/maximum-product-of-splitted-binary-tree/description/
// 1339. 分裂二叉树的最大乘积
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
const int MOD = 1e9+7;
class Solution {
private:
// 二叉树所有节点之和
int sum = 0;
// 分隔后,两棵树的最小差值
int diff = 0x3f3f3f3f;
// 分隔后一棵树的和
long long cutleft = 0;
// 分隔后另一颗树的和
long long cut = 0;
public:
// 计算sum
int travelSum(TreeNode* root)
{
if(root == nullptr)
{
return 0;
}
int leftv = travelSum(root->left);
int rightv = travelSum(root->right);
return root->val + leftv + rightv;
}
// 获取最小的diff 时,cut 和cutleft 的值
int travelCal(TreeNode* root)
{
if(root == nullptr)
{
return 0;
}
// 左子树的和
int leftv = travelCal(root->left);
// 右子树的和
int rightv = travelCal(root->right);
// 当前树的和
int tmpcut = root->val + leftv + rightv;
// 整颗树的和 - 当前树的和
int tmpcutleft = sum - tmpcut;
// 当前树的和 和 除去当前树之后的数的和 的绝对值
int tmpdiff = abs(tmpcut - tmpcutleft);
// 找到最合适的值
if(diff > tmpdiff)
{
diff = tmpdiff;
cut = tmpcut;
cutleft = tmpcutleft;
}
return tmpcut;
}
int maxProduct(TreeNode* root) {
sum = travelSum(root);
travelCal(root);
// 使用long long 接住
long long res = (cut*cutleft) % MOD;
return res;
}
};
复杂度分析
时间复杂度:构造过程是 O(N),其中 n 是二叉树中的节点个数,每个节点都会遍历一次。
空间复杂度:构造过程是O(logN) ,其中logN 为二叉树的高度。
题目感悟
注意本题可能会越界,需要使用long long。
更多相关知识:github.com/pingguo1987…