Maximum Path Sum in a Binary Tree
Given a binary tree, the task is to find the maximum path sum. The path may start and end at any node in the tree.
Example:
Input:
Output: 42
Explanation: Max path sum is represented using green colour nodes in the above binary tree.Input:
Output: 31
Explanation: Max path sum is represented using green colour nodes in the above binary tree.
Approach:
If the maximum sum path in a binary tree passes through the root, there are four possible cases to consider:
- The path consists only the root itself, without involving any children.
- The path starts at the root and extends downward through its right child, possibly continuing to the bottom of the right subtree.
- The path starts at the root and extends downward through its left child, possibly continuing the bottom of the left subtree.
- The path includes the root and spans both the left and right children.
The idea is to keep track of all four paths for each subtree of the tree and pick up the max one in the end.
Implementation:
For each subtree, we want to find the maximum path sum that starts at its root and goes down through either its left or right child. To do this, we create a recursive function (lets say MPS(current root)) that calculates and returns the maximum path sum starting from the root and extending downward through one of its children.
Within the same function, we can also calculate the maximum path sum for the current subtree and compare it with the final answer. This is done by combining the MPS(current root -> left) and MPS(current root -> right) with the value of the current root.
Note that if the MPS() from the left or right child is negative, we simply ignore it while calculating the maximum path sum for the current subtree.
// Returns the maximum path sum in the subtree with the current node as an endpoint.
// Also updates 'res' with the maximum path sum.
int maxPathSumUtil(Node* root, int& res) {
// Base case: return 0 for a null node
if (root == NULL)
return 0;
// Calculate maximum path sums for left and right subtrees
int l = max(0, maxPathSumUtil(root->left, res));
int r = max(0, maxPathSumUtil(root->right, res));
// Update 'res' with the maximum path sum passing through the current node
res = max(res, l + r + root->data);
// Return the maximum path sum rooted at this node
return root->data + max(l, r);
}
// Returns maximum path sum in tree with given root
int maxPathSum(Node* root) {
int res = root->data;
// Compute maximum path sum and store it in 'res'
maxPathSumUtil(root, res);
return res;
}
class GfG {
// Returns the maximum path sum in the subtree with the current node as an endpoint.
// Also updates 'res' with the maximum path sum.
static int maxPathSumUtil(Node root, int[] res) {
// Base case: return 0 for a null node
if (root == null) return 0;
// Calculate maximum path sums for left and right subtrees
int l = Math.max(0, maxPathSumUtil(root.left, res));
int r = Math.max(0, maxPathSumUtil(root.right, res));
// Update 'res' with the maximum path sum passing through the current node
res[0] = Math.max(res[0], l + r + root.data);
// Return the maximum path sum rooted at this node
return root.data + Math.max(l, r);
}
// Returns maximum path sum in tree with given root
static int maxPathSum(Node root) {
int[] res = {root.data};
// Compute maximum path sum and store it in 'res'
maxPathSumUtil(root, res);
return res[0];
}
# Returns the maximum path sum in the subtree with the current node as an endpoint.
# Also updates 'res' with the maximum path sum.
def maxPathSumUtil(root, res):
# Base case: return 0 for a null node
if root is None:
return 0
# Calculate maximum path sums for left and right subtrees
l = max(0, maxPathSumUtil(root.left, res))
r = max(0, maxPathSumUtil(root.right, res))
# Update 'res' with the maximum path sum passing through the current node
res[0] = max(res[0], l + r + root.data)
# Return the maximum path sum rooted at this node
return root.data + max(l, r)
# Returns maximum path sum in tree with given root
def maxPathSum(root):
res = [root.data]
# Compute maximum path sum and store it in 'res'
maxPathSumUtil(root, res)
return res[0]
// Returns the maximum path sum in the subtree with the current node as an endpoint.
// Also updates 'res' with the maximum path sum.
static int maxPathSumUtil(Node root, ref int res) {
// Base case: return 0 for a null node
if (root == null)
return 0;
// Calculate maximum path sums for left and right subtrees
int l = Math.Max(0, maxPathSumUtil(root.left, ref res));
int r = Math.Max(0, maxPathSumUtil(root.right, ref res));
// Update 'res' with the maximum path sum passing through the current node
res = Math.Max(res, l + r + root.data);
// Return the maximum path sum rooted at this node
return root.data + Math.Max(l, r);
}
// Returns maximum path sum in tree with given root
static int maxPathSum(Node root) {
int res = root.data;
// Compute maximum path sum and store it in 'res'
maxPathSumUtil(root, ref res);
return res;
}
// Returns the maximum path sum in the subtree with the current node as an endpoint.
// Also updates 'res' with the maximum path sum.
function maxPathSumUtil(root, res) {
// Base case: return 0 for a null node
if (root === null) return 0;
// Calculate maximum path sums for left and right subtrees
const l = Math.max(0, maxPathSumUtil(root.left, res));
const r = Math.max(0, maxPathSumUtil(root.right, res));
// Update 'res' with the maximum path sum passing through the current node
res.value = Math.max(res.value, l + r + root.data);
// Return the maximum path sum rooted at this node
return root.data + Math.max(l, r);
}
// Returns maximum path sum in tree with given root
function maxPathSum(root) {
const res = { value: root.data };
// Compute maximum path sum and store it in 'res'
maxPathSumUtil(root, res);
return res.value;
}
Output
42
Time Complexity: O(n), where n is the number of nodes in the Binary Tree.
Auxiliary Space: O(h), where h is the height of the tree.