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 does not need to go through the root.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
一开始,我觉得可以直接从每个点的和开始找起,得到每个点的和,那么最大和就是(最大的和-最小的和或者就是最大的和)但是再仔细想想,其实会发现,你很难求出每个点的和,因为你不知道到底按照什么样的顺序来进行遍历树。
那么,换个思路,直接求每个点的最大路径和。
每个点的最大路径和 =
1、左子树的最大路径和+该点的大小
2、右子树的最大路径和+该店的大小
3、左子树的最大路径和+右子树的最大路径和+该点的大小
4、该点的大小
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private List<Integer> list = new LinkedList<Integer>();
private int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
getPathSum(root);
for(Integer i : list) {
max = max>i?max:i;
}
return max;
}
private int getPathSum(TreeNode root) {
if(root==null) return 0;
int maxLeft = getPathSum(root.left);
int maxRight = getPathSum(root.right);
maxLeft = maxLeft>0?maxLeft:0;
maxRight = maxRight>0?maxRight:0;
list.add(maxLeft+maxRight+root.val);
return maxLeft+maxRight+root.val;
}
}
看起来好像没什么逻辑问题,一跑就发现错的一塌糊涂。错在哪里呢?如下:
1
2 3
4 5 6 7
实际应是5+2+1+3+&=18 而不是4+2+5+1+3+6+7=28
因为4+5+2 也即左子树+右子树+该节点的和 是不可以再加别的结点了。
代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private List<Integer> list = new LinkedList<Integer>();
private int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
getPathSum(root,0);
for(Integer i : list) {
max = max>i?max:i;
}
return max;
}
//flag==0 代表不可以再往上
//flag==1 代表还可以再往上
private int getPathSum(TreeNode root,int flag) {
if(root==null) return 0;
int maxLeft0 = getPathSum(root.left,0);
int maxLeft1 = getPathSum(root.left,1);
int maxRight0 = getPathSum(root.right,0);
int maxRight1 = getPathSum(root.right,1);
if(flag==0) {
int max0 = Math.max(maxLeft1,0)+Math.max(maxRight1,0)+root.val;
list.add(max0);
return max0;
} else {
int max1 = Math.max(Math.max(maxLeft1,maxRight1),0)+root.val;
list.add(max1);
return max1;
}
}
}
跑的两个小数据没有问题,但是整体跑的时候,TLE了。
看了下别人的解答,发现,比我大简单多了,不过思想差不多,通过函数来返回左子树+该节点或者右子树+该节点,通过全局变量 maxSum来保存左子树+右子树+该节点的最大值。
代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
getPathSum(root);
return maxSum;
}
private int getPathSum(TreeNode root) {
if(root==null) return 0;
int leftMax = getPathSum(root.left);
int rightMax = getPathSum(root.right);
maxSum = Math.max(leftMax+rightMax+root.val,maxSum);
int ret = Math.max(rightMax,leftMax)+root.val;
return ret>0?ret:0;
}
}