给你一棵二叉树,它的根为 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] 之间。
Related Topics
  • 深度优先搜索
  • 二叉树
  • \n
  • 👍 59
  • 👎 0
  • 题解

    1.求出二叉树总和

    2.找到一个节点上的总和,最接近于树上总和的一半

    3.求出面积即是结果

    4.为啥是一半呢,看代码中间的注释

    
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        double sum = 0;
        double halfSum = 0;
        double nearHalf = 0;
        public int maxProduct(TreeNode root) {
            //两数之和固定,两数需要乘积最大化,则两个数应当无限接近,最优解为两数之和的一半
            //类似于一根固定长的绳子摆成矩形的两个相邻边,要求使矩形面积最大化,这是一个高中还是初中数学题来着
            //假设这条绳子长为 2x,分成两段
            // 一段长度为 x - t , 另一段的长度就为 x + t
            //( x - t )* ( x + t ) <= x^2
            // x^2 + x*t - x*t - t^2  <= x^2
            // x^2 - t^2 <= x^2
            // 有且只有当t = 0 的时候面积最大
            sum = dfs(root);
            halfSum = sum/2;
            dfsNearHalf(root);
            return (int)((sum-nearHalf)*nearHalf%1000000007);
    
        }
    
    
        private double dfsNearHalf(TreeNode node){
            if(node==null){
                return 0;
            }
            double tempSum = node.val + dfsNearHalf(node.left) + dfsNearHalf(node.right);
            nearHalf = Math.abs(nearHalf - halfSum) > Math.abs(tempSum-halfSum)?tempSum:nearHalf;
            return tempSum;
        }
    
    
        private double dfs(TreeNode node){
            if(node==null){
                return 0;
            }
            return node.val + dfs(node.left) + dfs(node.right);
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)

    其实也可以第一DFS之后把结果缓存起来,在然后遍历缓存起来的结果,找到最接近的那个,或者在第二次dfs的之后从缓存里取结果,而不是再算一次,但是这两种我都试了下。效率还没有再算一次的效率高。