Leetcode Weekly – 174 – 3

Time:2020-9-19

1339. Maximum product of split binary trees

Hi, everyone. I’m a pig. Welcome to the weekly leetcode quiz of the “baby can understand” series.

This is the third question in 174 and 1339 in the list of topics – “the maximum product of a split binary tree.”

Title Description

Here is a binary tree whose root isroot。 Please delete one edge so that the binary tree is split into two subtrees, and the product of their subtrees and is as large as possible.

Since the answer may be very large, please take the result of 10 ^ 9 + 7 and return it.

Example 1:

Leetcode Weekly - 174 - 3

Input: root = [1,2,3,4,5,6]
Output: 110
Explanation: remove the red edge and get 2 subtrees with 11 and 10, respectively. The product of them is 110 (11 * 10)

Example 2:

Leetcode Weekly - 174 - 3

Input: root = [1, null, 2, 3, 4, null, null, 5, 6]
Output: 90
Explanation: remove the red edge and get 2 subtrees, 15 and 6, respectively. Their product is 90 (15 * 6)

Example 3:

Input: root = [2,3,9,10,7,8,6,5,4,11,1]
Output: 1025

Example 4:

Input: root = [1,1]
Output: 1

Tips:

  • Each tree has at most50000Nodes with at least2Nodes.
  • The value of each node is in the[1, 10000]Between.

Official difficulty

MEDIUM

Solutions

The title provides the root node of a binary tree. We need to delete an edge to make the binary tree become two binary trees. The requirement is that the product of the sum of the two binary trees is the smallest after the sum of each node in the two binary trees is calculated respectively.

I don’t know what the friends think, but the first reaction of the pig after reading the topic is to traverse it first. After all, no matter how good the play is, if it only faces one root node. When it comes to traversing the binary tree, I want to write less code. The pig’s first reaction is to use recursion to realize depth first traversal.

Next, we need to find the maximum product of two sums after splitting. Since this tree will not change after it is given, the sum value of all nodes is actually fixed. For this definite value, if we divide it into two addends to maximize their product, then these two numbers should be as close as possible to one-half of the sum. I believe that here, many small partners can think of. However, in the future, if you directly deal with this problem in a mathematical way, the pig will not understand. I hope you can help me.

There is no mathematical method, the pig can only use the computer method. We can imagine that after removing an edge, we can split into two binary trees. One of them must have its vertex downstream of the edge we just cut off. In other words, after being disassembled from the current position, it is actually divided into two parts, namely, the binary tree with the current node as the vertex, and other nodes.

Having figured out this point, the sum mentioned above is fixed. Then our thinking is probably clear.

Direct scheme

We can calculate the sum of all the nodes first. Then, for each node, we can also calculate the sum of the sub binary trees with its vertex. Then the rest will be known. After doing this for every possible node, we can find the largest product.

Based on this idea, our specific process is as follows:

  1. Traversing the binary tree, get the sum of all node values.
  2. Traversing the binary tree, for each possible node, suppose to split from here, then calculate the possible product, and record the maximum value.
  3. Returns the largest product.

Based on this process, we can implement code similar to the following:

const maxProduct = root => {
  let sum = max = 0;
  sum = helper(root);
  helper(root);
  return max % (10 ** 9 + 7);

  function helper(node) {
    const subSum = node.val + (node.left ? helper(node.left) : 0) + (node.right ? helper(node.right) : 0);
    sum && subSum * (sum - subSum) > max && (max = subSum * (sum - subSum));
    return subSum;
  }
};

optimization

In the above code, we traverse the whole binary tree twice, the first time is to calculate the total, and the second time is to calculate and judge the sub binary tree of each node.

I don’t know if my friends have found out. In fact, what we calculated in the second traversal can also be obtained in the first traversal. And the only thing that couldn’t be calculated at first was the product of the difference of the sum. Then we can actually record all the previous contents and calculate them directly after getting the sum.

Based on this optimization idea, our specific process is as follows:

  1. Traversing the binary tree, get the sum of all the node values, and record the sum of the sub binary tree headed by each node.
  2. Try the sum of these sub binary trees and calculate the maximum product.

Based on this process, we can implement code similar to the following:

const maxProduct = root => {
  const subSums = new Uint32Array(50000);
  let max = idx = 0;
  const sum = helper(root);
  for (let i = 0; i < idx; ++i) {
    const val = subSums[i];
    val * (sum - val) > max && (max = val * (sum - val));
  }
  return max % (10 ** 9 + 7);

  function helper(node) {
    const subSum = node.val + (node.left ? helper(node.left) : 0) + (node.right ? helper(node.right) : 0);
    subSums[idx++] = subSum;
    return subSum;
  }
};

summary

The logic of this problem is not complicated, but it is a very routine content. The key point is to communicate with the situation after our split, that is, after the split mentioned in the analysis, part of it must be a sub binary tree headed by the current node. The rest is to apply depth first traversal to achieve.

In our so many weeks after the solution of the problem, I believe that the partners have gradually begun to familiar with these routines. Suddenly, I felt that what piggy did was meaningful. I wagged pig’s tail happily<

Related links

  • Weekly contest 174 topic list
  • Repo
  • My segment fault column
  • My Zhihu column

Leetcode Weekly - 174 - 3