124. Binary Tree Maximum Path Sum

124. Binary Tree Maximum Path Sum

Problem Solving - Day 71

ยท

4 min read

Hello, reader ๐Ÿ‘‹๐Ÿฝ ! Welcome to day 71 of the series on Problem Solving. Through this series, I aim to pick up at least one question everyday and share my approach for solving it.

Today, I will be picking up LeetCode's daily challenge problem: 124. Binary Tree Maximum Path Sum.


๐Ÿค” Problem Statement

  • A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them.

  • A node can only appear in the sequence at most once. Note that the path does not need to pass through the root.

  • The path sum of a path is the sum of the node's values in the path.

  • Given the root of a binary tree, return the maximum path sum of any non-empty path.

  • E.g.:

    • [1,2,3] => 6

    • [-10,9,20,null,null,15,7] => 42


๐Ÿ’ฌ Thought Process - Left, right subtree sum

  • The naive way to solve this problem would be to check for all the possible routes through any node root.

  • So the possible routes could be:

    • root (since in the question they have said a path contains at least 1 node)

    • root and the left subtree

    • root and the right subtree

    • root, left and right subtree

  • We'd be finding the path sum of say a node root in the tree (let's assume it's somewhere in the mid height of the tree) more than once => when processing every ancestor as well as when processing all the nodes rooted at this node.

  • This is redundant and we don't need to do this. The key to understanding the solution to the problem is that we find left and right subtree path sum at every node and try to find the best path.

  • We'll calculate the path sum in the left subtree of the current node. We'll calculate the path sum in the right subtree of the current node.

  • Since we have to maximise the the path sum, we will ensure that we'll only include positive values. So if any subtree sum results in a negative value, we will ignore it.

  • We will calculate the total sum of the path that joins the left and right subtree by the root.

  • Hence our sum would be: pathSum = leftSubtreeSum + root.val + rightSubtreeSum.

    • This sum would be compared with the previous maximumPathSum value. If this pathSum > maximumPathSum, then we update maximumPathSum with pathSum.
  • It is also worth noting that the a root in the path can only be connected to two another nodes: parent and child or the two children of node.

  • It could never be the case where a node root can be connected to both its children and parent.

  • Hence at every subtree rooted at root, we can either include the root and its left subtree or the root and it's right subtree for the path sum in the path of its ancestor.

  • From the path sum of subtree rooted at root, we will only return the maximum of the root.val + leftSubtreeSum or root.val + rightSubtreeSum.

  • And we will continue the same thing for every node from the left most node. Basically we will do a post order traversal.

  • Below is the illustration for the above process.

๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ’ป Solution - Left, right subtree sum

  • Below is the code for the approach for calculating the difference of every path using the maximum and minimum nodes along that path.
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int maxSum = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        if(root == null) return 0;

        helper(root);

        return maxSum;
    }

    private int helper(TreeNode root) {
        if(root == null) return 0;

        int left = helper(root.left);
        if(left < 0) left = 0;
        int right = helper(root.right);
        if(right < 0) right = 0;
        int val = root.val;
        maxSum = Math.max(maxSum, left + right + val);

        return val + Math.max(left, right);
    }
}
Time Complexity: O(n)
  - n = number of nodes in the tree
Space Complexity: O(n)
  - n = number of nodes in the tree


Conclusion

That's a wrap for today's problem. If you liked my explanation then please do drop a like/ comment. Also, please correct me if I've made any mistakes or if you want me to improve something!

Thank you for reading!