Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. For example, given the below binary tree
1 / \ 2 3
the result is 6.
Analysis
1) Recursively solve this problem
2) Get largest left sum and right sum
2) Compare to the stored maximum
Java Solution
We can also use an array to store value for recursive methods.
public int maxPathSum(TreeNode root) { int max[] = new int[1]; max[0] = Integer.MIN_VALUE; calculateSum(root, max); return max[0]; } public int calculateSum(TreeNode root, int[] max) { if (root == null) return 0; int left = calculateSum(root.left, max); int right = calculateSum(root.right, max); int current = Math.max(root.val, Math.max(root.val + left, root.val + right)); max[0] = Math.max(max[0], Math.max(current, left + root.val + right)); return current; } |
–
Solution that can be parallel as the max isn’t passed inside, but rather returned – hence the parallelizm:
class Helper
int cMax;
int oMax;
int maxPathSum(Node n)
{
return maxPathSum(n).oMax;
}
Helper maxPathSum(Node n)
{
if (n == null) return 0;
Helper hLeft = maxPathSum(n.left);
Helper hRight = maxPathSum(n.right);
int cMax = Math.max(n.val, hLeft.cMax + n.val, n.val + hRight.cMax);
int oMax = Math.max(cMax, hLeft.cMax + n.val + hRight.cMax, hLeft.oMax, hRight.oMax);
return new Helper(cMax, oMax);
}
Fails for this input
[-10,9,20,null,null,15,7]
Output
34
Expected
42
better solution :
public int findMaxSum(Node root){
Node node = root;
return findMaxSum(node,true);
}
private int findMaxSum(Node node, boolean flag) {
if(node == null){
return 0;
}
if(flag){
return node.value + findMaxSum(node.left,false) + findMaxSum(node.right, false);
}
return node.value + Math.max(findMaxSum(node.left,false), findMaxSum(node.right, false));
}
You should check this
http://www.geeksforgeeks.org/find-maximum-path-sum-in-a-binary-tree/
Can you add the snippet to output the actual path for it? e.g. in this format 3->1->2
even with your given tree, 32 is the correct answer. I fail to see how 42 is the correct answer.
we can achieve the same without the array[] input
private static int maxPathSum(TreeNode node, int maxSum) {
if(node == null)
return 0;
int leftSum = maxPathSum(node.left, maxSum);
int rightSum = maxPathSum(node.right, maxSum);
int max = Math.max(node.val, Math.max(node.val+leftSum, node.val+rightSum));
int maxTemp = Math.max(maxSum, Math.max(max,node.val+leftSum+ rightSum));
return maxTemp;
}
i think we cna achieve the same without array as input
private static int maxPathSum(TreeNode node, int maxSum) {
if(node == null)
return 0;
int leftSum = maxPathSum(node.left, maxSum);
int rightSum = maxPathSum(node.right, maxSum);
int max = Math.max(node.val, Math.max(node.val+leftSum, node.val+rightSum));
int maxTemp = Math.max(maxSum, Math.max(max,node.val+leftSum+ rightSum));
return maxTemp;
}
Because of the recursion, if you pass in max instead of max[], given java pass by value, it will still store the result Integer.MIN_VALUE to the new call stack.
Your code fails for this tree:
Node root = new Node(10);
root.left = new Node(2);
root.right = new Node(10);
root.left.left = new Node(20);
root.left.right = new Node(1);
root.right.right = new Node(-25);
root.right.right.left = new Node(3);
root.right.right.right = new Node(4);
It should return 42, but returns 32 instead.
There is only one solution …
I do think the same
why we need use an array max[], can we use and static int variable to instead?
understand why such recurstion lsum, rsum and result is passed with pointer here at with same code and same example : http://goo.gl/wuatmP
Not timeout from my side.
I get 53 even with the first solution
thanks, nice and easy.
Got it. I didn’t consider negative situation
Why don’t just find the max sum on left and right, then return (root.value + left_max + right_max)?
First solution will work only for positive numbers while second will take care of both(+ve and -ve numbers)
Great solution! But It looks that it can be more elegant
public int getMax(){
return getMax(root);
}
private int getMax(Node x){
if(x == null){
return 0;
}
int left = getMax(x.left);
int right = getMax(x.right);
return x.value + (left > right ? left:right);
}
These two solutions are timeout on OJ. How to solve it?
Shouldn’t the last line of the first solution be “return node.value + left + right” rather than “return node.value + Math.max(left, right)”?
First solution seems to be giving wrong answer.
TreeNode root = new TreeNode(10);
TreeNode left1 = new TreeNode(5);
TreeNode left2 = new TreeNode(3);
TreeNode right1 = new TreeNode(15);
TreeNode right2 = new TreeNode(20);
root.left = left1;
left1.left = left2;
root.right = right1;
right1.right = right2;
Answer should be 53 but it is coming out to be 45. Second solution’s output for the same input is 53.
Thank you for
sharing this and I think I need them, the information
has been looking for.
Best solution I’ve seen so far, thank you!