二叉树_题目18:1339. 分裂二叉树的最大乘积

43 阅读3分钟

题目18:1339. 分裂二叉树的最大乘积

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 棵子树,和分别是 156 。它们的乘积为 9015*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…