124. Binary Tree Maximum Path Sum
题目:
Given a binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
链接:https://leetcode.com/problems/binary-tree-maximum-path-sum/#/description
5/10/2017
算法班
4ms, 8%
感觉能够独立解决hard题了,虽然解得很💩,但是内心还是有些小激动!
思路:
后序遍历。这是能做出来这道题我想到的。
建立一个类,保存某节点里其左右子树的max path sum(不一定包含左右子节点)名为subtreeMax,和包含左右子节点的max path sum的onesizeMax
subtreeMax忽略left, right为空的情况,值为max(left.subtreeMax, right.subtreeMax, left.onesizeMax + right.onesizeMax + root.val, root.val)这4部分比较而来
onesizeMax忽略left, right为空的情况,值为max(left.onesizeMax + root.val, right.onesizeMax + root.val, root.val)这3部分比较而来。
globalMax为max(globalMax, subtreeMax, onesizeMax)这3部分比较而来。
注意:
开始globalMax为Result当中的一个变量,但是测到最后一个test case超时,变成global variable之后顺利通过。问题可能出在多了几次globalMax的比较,或者构造函数的开销?
1 public class Solution { 2 class Result { 3 int subtreeMax; // up and down 4 int onesizeMax; // onesize and include current node 5 Result(int subtreeMax, int onesizeMax) { 6 this.subtreeMax = subtreeMax; 7 this.onesizeMax = onesizeMax; 8 } 9 } 10 int globalMax = Integer.MIN_VALUE; 11 public int maxPathSum(TreeNode root) { 12 if (root == null) { 13 return Integer.MIN_VALUE; // shouldn't go here 14 } 15 Result ret = findMaxPath(root); 16 return globalMax; 17 } 18 private Result findMaxPath(TreeNode root) { 19 if (root == null) { 20 return null; 21 } 22 Result left = findMaxPath(root.left); 23 Result right = findMaxPath(root.right); 24 25 int tmpSubtreeMax = Integer.MIN_VALUE, tmpOnesizeMax = Integer.MIN_VALUE, tmpMax = Integer.MIN_VALUE; 26 if (left != null && right != null) { 27 tmpSubtreeMax = Math.max(left.onesizeMax + right.onesizeMax + root.val, left.subtreeMax); 28 tmpSubtreeMax = Math.max(tmpSubtreeMax, right.subtreeMax); 29 tmpOnesizeMax = Math.max(left.onesizeMax + root.val, right.onesizeMax + root.val); 30 } else if (left != null) { 31 tmpSubtreeMax = Math.max(left.onesizeMax + root.val, left.subtreeMax); 32 tmpOnesizeMax = left.onesizeMax + root.val; 33 } else if (right != null) { 34 tmpSubtreeMax = Math.max(right.onesizeMax + root.val, right.subtreeMax); 35 tmpOnesizeMax = right.onesizeMax + root.val; 36 } 37 tmpSubtreeMax = Math.max(root.val, tmpSubtreeMax); 38 tmpOnesizeMax = Math.max(tmpOnesizeMax, root.val); 39 tmpMax = Math.max(Math.max(tmpMax, tmpSubtreeMax), tmpOnesizeMax); 40 globalMax = Math.max(tmpMax, globalMax); 41 42 return new Result(tmpSubtreeMax, tmpOnesizeMax); 43 } 44 }
然而我的解法太麻烦了,别人的解法
套用我自己的思路,left为含左节点的onesize max path sum, right为含右节点的onesize max path sum,第15行返回包含当前节点的单边(onesize)max path sum
那么双边subtree max path sum呢?在第14行进行比较,并存入global max。所以第14行其实做的是当前层subtree 双边path sum和之前子树里subtree双边path sum最大值的比较。双边的max path sum作为max时考虑的一部分,没有在递归中保存。
所以这个算法写起来非常简洁。我要学会。
Here's my ideas:
- A path from start to end, goes up on the tree for 0 or more steps, then goes down for 0 or more steps. Once it goes down, it can't go up. Each path has a highest node, which is also the lowest common ancestor of all other nodes on the path.
- A recursive method
maxPathDown(TreeNode node)
(1) computes the maximum path sum with highest node is the input node, update maximum if necessary (2) returns the maximum sum of the path that can be extended to input node's parent.
The most tricky point is the global variable maxValue in the following sentence:
maxValue = Math.max(maxValue, left + right + node.val);
The second maxValue contains the bigger between the left sub-tree and right sub-tree.
if (left + right + node.val < maxValue ) then the result will not include the parent node which means the maximum path is in the left branch or right branch.
1 public class Solution { 2 int max = Integer.MIN_VALUE; 3 4 public int maxPathSum(TreeNode root) { 5 helper(root); 6 return max; 7 } 8 9 private int helper(TreeNode root) { 10 if(root == null) 11 return 0; 12 int left = Math.max(helper(root.left), 0); 13 int right = Math.max(helper(root.right), 0); 14 max = Math.max(max, root.val + left + right); 15 return root.val + Math.max(left, right); 16 } 17 }
以上是讨论里几乎唯一的答案版本了
更多讨论
https://discuss.leetcode.com/category/132/binary-tree-maximum-path-sum