这是一道 hard 题,但是看到题到了解到思路仅用了 5 分钟,然而最后调试以及修改枝叶错误画了半个小时。总之做出来了,开心。。。
题目描述
思路分析
以下图是我一开始的思路。我的想法是,对于一个简单二叉树,所有情况无非就是:root,(root,left),(root,left,right),(root,right)
那么从子树开始,从下至上递归,求得每个简单二叉树能够起到的最大作用传上去。
当然,还有两种情况没考虑,那就是单独的(left)
和(right)
这两种情况是不能够传上去的。
(当然不止,但由于太菜第一思路没想那么多)
然后出现了错误,错例是一个仅有根节点,且根节点为-3
的树。原因就在于,当 root 等于 null 时,我返回的是 0,因此最大值被确认为 0。所以,当 root 等于 null 时,应当返回负无穷。
好了,这个错误跨过去之后,就是下一个错误。错误的测例为:
然后仔细观察就能发现,其实当一个简单二叉树的三个节点全部选中之后,它是不能继续往上走的。
所以不能继续往上走的有三种:
(left), (right), (root, left, right)
能继续往上走的有三种:
(root, left), (root, right), (root)
思路说完了,上代码:
public class Solution1 {
private int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
helper(root);
return max;
}
public int helper(TreeNode root) {
if (root == null) return Integer.MIN_VALUE;
int[] cases = new int[6];
int max_r = Integer.MIN_VALUE;
int left = helper(root.left);
int right = helper(root.right);
cases[0] = left == Integer.MIN_VALUE ? Integer.MIN_VALUE : left + root.val;
cases[1] = right == Integer.MIN_VALUE ? Integer.MIN_VALUE : right + root.val;
cases[2] = root.val;
cases[3] = left;
cases[4] = right;
cases[5] = (left == Integer.MIN_VALUE || right == Integer.MIN_VALUE) ? Integer.MIN_VALUE : left + right + root.val;
for (int i = 0; i < 6; ++i) {
if (cases[i] > max) {
max = cases[i];
}
if (i < 3) {
if (cases[i] > max_r) {
max_r = cases[i];
}
}
}
return max_r;
}
}