DP on Trees Maximum Path Sum in DSA Java - Time & Space Complexity
We want to understand how the time needed to find the maximum path sum in a tree grows as the tree gets bigger.
Specifically, how the number of nodes affects the work done.
Analyze the time complexity of the following code snippet.
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int v) { val = v; }
}
int maxSum = Integer.MIN_VALUE;
int maxPathSum(TreeNode root) {
maxSum = Integer.MIN_VALUE;
helper(root);
return maxSum;
}
int helper(TreeNode node) {
if (node == null) return 0;
int left = Math.max(0, helper(node.left));
int right = Math.max(0, helper(node.right));
maxSum = Math.max(maxSum, left + right + node.val);
return node.val + Math.max(left, right);
}
This code finds the maximum sum of values along any path in a binary tree, using recursion.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls visiting each node once.
- How many times: Each node is visited exactly one time during recursion.
As the number of nodes grows, the function visits each node once, doing a fixed amount of work per node.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The work grows directly in proportion to the number of nodes.
Time Complexity: O(n)
This means the time to find the maximum path sum grows linearly with the number of nodes in the tree.
[X] Wrong: "The recursion visits nodes multiple times, so time is more than linear."
[OK] Correct: Each node is visited once, and results are combined on the way back, so no repeated work happens.
Understanding this linear time complexity helps you explain how efficient your tree algorithms are, a key skill in interviews.
"What if the tree was not binary but had many children per node? How would the time complexity change?"
Practice
Maximum path sum means the largest sum of node values along any path in the tree.Solution
Step 1: Understand the definition of maximum path sum
The maximum path sum is the highest sum you can get by adding node values along any path in the tree. The path can start and end at any nodes.Step 2: Differentiate from other sums
It is not just the sum of all nodes, nor the max single node, nor limited to root-to-leaf paths. It considers any path.Final Answer:
The largest sum of node values along any path in the tree -> Option DQuick Check:
Maximum path sum = largest path sum [OK]
- Confusing maximum path sum with sum of all nodes
- Thinking path must start at root
- Considering only single node values
TreeNode?Solution
Step 1: Check method return type and parameters
The method should return an int (the max sum) and accept a TreeNode parameter.Step 2: Validate Java syntax
public int maxPathSum(TreeNode root) uses correct syntax. int maxPathSum(TreeNode root) throws Exception unnecessarily throws Exception, the void version returns wrong type, the version without return type is invalid.Final Answer:
public int maxPathSum(TreeNode root) -> Option BQuick Check:
Correct method signature returns int and takes TreeNode [OK]
- Using void return type instead of int
- Missing return type in method signature
- Adding unnecessary throws Exception
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int v) { val = v; }
}
public class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
private int maxGain(TreeNode node) {
if (node == null) return 0;
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
int priceNewPath = node.val + leftGain + rightGain;
maxSum = Math.max(maxSum, priceNewPath);
return node.val + Math.max(leftGain, rightGain);
}
public static void main(String[] args) {
TreeNode root = new TreeNode(-10);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
Solution sol = new Solution();
System.out.println(sol.maxPathSum(root));
}
}Solution
Step 1: Trace maxGain for each node
Calculate maxGain for leaves: 9 returns 9, 15 returns 15, 7 returns 7. For node 20: leftGain=15, rightGain=7, priceNewPath=20+15+7=42, maxSum=42. For root -10: leftGain=9, rightGain=20+15=35 (maxGain returns node.val + max(leftGain,rightGain), so for right child maxGain=35), priceNewPath at root = -10 + 9 + 35 = 34, maxSum remains 42.Step 2: Determine maxSum after full traversal
maxSum is updated to 42 at node 20, which is the maximum path sum.Final Answer:
42 -> Option AQuick Check:
Max path sum = 42 [OK]
- Ignoring negative node values
- Not resetting maxSum correctly
- Confusing return value with maxSum
private int maxGain(TreeNode node) {
if (node == null) return 0;
int leftGain = maxGain(node.left);
int rightGain = maxGain(node.right);
int priceNewPath = node.val + leftGain + rightGain;
maxSum = Math.max(maxSum, priceNewPath);
return node.val + Math.max(leftGain, rightGain);
}Solution
Step 1: Analyze handling of negative gains
Without Math.max(..., 0), negative leftGain or rightGain reduce path sum incorrectly.Step 2: Fix by ignoring negative gains
Use int leftGain = Math.max(maxGain(node.left), 0) and similarly for rightGain to ignore negative paths.Final Answer:
Add Math.max(..., 0) to leftGain and rightGain to ignore negative sums -> Option CQuick Check:
Ignore negative gains with Math.max(..., 0) [OK]
- Not ignoring negative sums causing wrong maxSum
- Changing return type incorrectly
- Removing maxSum update line
Choose the best description of the approach.
Solution
Step 1: Understand dynamic programming on trees
Post-order traversal ensures children are processed before parent, allowing calculation of max gains from subtrees.Step 2: Apply max gain logic ignoring negative sums
At each node, calculate max gain from left and right children ignoring negatives, update global max path sum with node plus both gains, and return node plus max gain of one side for parent's use.Final Answer:
Use post-order traversal; at each node, compute max gain from left and right ignoring negatives; update global max with node value plus both gains; return node value plus max gain of one side -> Option AQuick Check:
Post-order + max gain ignoring negatives = correct DP approach [OK]
- Using wrong traversal order
- Summing all nodes instead of max path
- Ignoring negative values in gains
Ready to prove it?
Pass the test and this pattern moves unknown
