Find the maximum path sum between two leaves of a binary tree
Last Updated :
14 Oct, 2024
Given a binary tree in which each node element contains a number. Find the maximum possible sum from one leaf node to another.
Examples:
Input:
Output: 27
Explanation: The maximum sum path may or may not go through the root. For example, in the following binary tree, the maximum sum is 27 (3 + 6 + 9 + 0 - 1 + 10).
To find the maximum path sum between two leaf nodes in a binary tree, traverse each node and recursively calculate the maximum sum from leaf to root in the left subtree of x (Find the maximum sum leaf to root path in a Binary Tree). Find the maximum sum from leaf to root in the right subtree of x. Add the above two calculated values and x->data compare the sum with the maximum value obtained so far and update the maximum value. Return the overall maximum value. The time complexity of the above solution is O(n2).
Approach:
We can find the maximum sum using single traversal of binary tree. The idea is to maintain two values in recursive calls. For every visited node x, we find the maximum root to leaf sum in left and right subtrees of x. We add the two values with x->data, and compare the sum with maximum path sum found so far.
Below is the implementation of above approach:
C++
// C++ program to find maximum path
//sum between two leaves of a binary tree
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// mxPathSum function to calculate maximum path sum
// between two leaves and maximum sum from node to leaf
// in a single traversal
int mxPathSum(Node *root, int &maxPathSum) {
// Base case: If the node is null,
// return 0
if (root == nullptr) {
return 0;
}
// Recursively calculate the maximum sum from
// node to leaf for left and right subtrees
int mxLeft = mxPathSum(root->left, maxPathSum);
int mxRight = mxPathSum(root->right, maxPathSum);
// If both left and right children exist,
// update maxPathSum
if (root->left != nullptr && root->right != nullptr) {
// This is the sum of the left path,
// right path, and the node's data
int maxSumPathViaNode = mxLeft + mxRight + root->data;
// Update the maximum sum path between
// two leaves
maxPathSum = max(maxPathSum, maxSumPathViaNode);
// Return the maximum sum from the current
// node to a leaf
return root->data + max(mxLeft, mxRight);
}
// If only one child exists, return the sum
// from the node to leaf
return root->data + (root->left ? mxLeft : mxRight);
}
// Function to return the maximum path
// sum between any two leaves in the binary tree
int findMaxSum(Node* root) {
// Edge case: If the tree is empty,
// return 0
if (root == nullptr) {
return 0;
}
int maxPathSum = INT_MIN;
// Call the helper function to
// compute the result
mxPathSum(root, maxPathSum);
return maxPathSum;
}
int main() {
// Construct a sample binary tree
//
// 1
// / \
// -2 3
// / \ / \
// 8 -1 4 -5
Node* root = new Node(1);
root->left = new Node(-2);
root->right = new Node(3);
root->left->left = new Node(8);
root->left->right = new Node(-1);
root->right->left = new Node(4);
root->right->right = new Node(-5);
int result = findMaxSum(root);
cout << result << endl;
return 0;
}
C
// C++ program to find maximum path
//sum between two leaves of a binary tree
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct Node {
int data;
struct Node *left, *right;
};
// mxPathSum function to calculate maximum path
// sum between two leaves and maximum sum from node
// to leaf in a single traversal
int mxPathSum(struct Node* root, int* maxPathSum) {
// Base case: If the node is null,
// return 0
if (root == NULL) {
return 0;
}
// Recursively calculate the maximum sum
// from node to leaf for left and right subtrees
int mxLeft = mxPathSum(root->left, maxPathSum);
int mxRight = mxPathSum(root->right, maxPathSum);
// If both left and right children exist,
// update maxPathSum
if (root->left != NULL && root->right != NULL) {
// This is the sum of the left path,
// right path, and the node's data
int maxSumPathViaNode = mxLeft + mxRight + root->data;
// Update the maximum sum path between two leaves
if (maxSumPathViaNode > *maxPathSum) {
*maxPathSum = maxSumPathViaNode;
}
// Return the maximum sum from the current
// node to a leaf
return root->data +
(mxLeft > mxRight ? mxLeft : mxRight);
}
// If only one child exists, return the sum
// from the node to leaf
return root->data + (root->left ? mxLeft : mxRight);
}
// Function to return the maximum path
// sum between any two leaves in the binary tree
int findMaxSum(struct Node* root) {
// Edge case: If the tree is empty,
// return 0
if (root == NULL) {
return 0;
}
int maxPathSum = INT_MIN;
// Call the helper function to compute
// the result
mxPathSum(root, &maxPathSum);
return maxPathSum;
}
struct Node* createNode(int x) {
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node));
newNode->data = x;
newNode->left = newNode->right = NULL;
return newNode;
}
int main() {
// Construct a sample binary tree
//
// 1
// / \
// -2 3
// / \ / \
// 8 -1 4 -5
struct Node* root = createNode(1);
root->left = createNode(-2);
root->right = createNode(3);
root->left->left = createNode(8);
root->left->right = createNode(-1);
root->right->left = createNode(4);
root->right->right = createNode(-5);
int result = findMaxSum(root);
printf("%d\n", result);
return 0;
}
Java
// Java program to find maximum path
// sum between two leaves of a binary tree
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// mxPathSum function to calculate maximum path sum
// between two leaves and maximum sum from node to
// leaf in a single traversal
static int mxPathSum(Node root, int[] maxPathSum) {
// Base case: If the node is null, return 0
if (root == null) {
return 0;
}
// Recursively calculate the maximum sum from
// node to leaf for left and right subtrees
int mxLeft = mxPathSum(root.left, maxPathSum);
int mxRight = mxPathSum(root.right, maxPathSum);
// If both left and right children exist,
// update maxPathSum
if (root.left != null && root.right != null) {
// This is the sum of the left path,
// right path, and the node's data
int maxSumPathViaNode = mxLeft + mxRight + root.data;
// Update the maximum sum path between
// two leaves
maxPathSum[0] = Math.max
(maxPathSum[0], maxSumPathViaNode);
// Return the maximum sum from the current
// node to a leaf
return root.data + Math.max(mxLeft, mxRight);
}
// If only one child exists, return the sum
// from the node to leaf
return root.data +
(root.left != null ? mxLeft : mxRight);
}
// Function to return the maximum path
// sum between any two leaves in the binary tree
static int findMaxSum(Node root) {
// Edge case: If the tree is empty, return 0
if (root == null) {
return 0;
}
int[] maxPathSum = new int[] {Integer.MIN_VALUE};
mxPathSum(root, maxPathSum);
return maxPathSum[0];
}
public static void main(String[] args) {
// Construct a sample binary tree
//
// 1
// / \
// -2 3
// / \ / \
// 8 -1 4 -5
Node root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(8);
root.left.right = new Node(-1);
root.right.left = new Node(4);
root.right.right = new Node(-5);
int result = findMaxSum(root);
System.out.println(result);
}
}
Python
# Python program to find maximum path
# sum between two leaves of a binary tree
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
def mxPathSum(root):
global maxPathSum
# Base case: If the node is null, return 0
if root is None:
return 0
# Recursively calculate the maximum sum from
# node to leaf for left and right subtrees
mxLeft = mxPathSum(root.left)
mxRight = mxPathSum(root.right)
# If both left and right children exist,
# update maxPathSum
if root.left is not None and root.right is not None:
# This is the sum of the left path,
# right path, and the node's data
maxSumPathViaNode = mxLeft + mxRight + root.data
# Update the maximum sum path between
# two leaves
maxPathSum = max(maxPathSum, maxSumPathViaNode)
# Return the maximum sum from the current node
# to a leaf
return root.data + max(mxLeft, mxRight)
# If only one child exists, return the sum from the
# node to leaf
return root.data + (mxLeft if root.left else mxRight)
def findMaxSum(root):
global maxPathSum
# Edge case: If the tree is empty,
# return 0
if root is None:
return 0
maxPathSum = float('-inf')
mxPathSum(root)
return maxPathSum
# Construct a sample binary tree
#
# 1
# / \
# -2 3
# / \ / \
# 8 -1 4 -5
root = Node(1)
root.left = Node(-2)
root.right = Node(3)
root.left.left = Node(8)
root.left.right = Node(-1)
root.right.left = Node(4)
root.right.right = Node(-5)
result = findMaxSum(root)
print( result)
C#
// C# program to find maximum path
// sum between two leaves of a binary tree
using System;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// mxPathSum function to calculate maximum path sum between two leaves
// and maximum sum from node to leaf in a single traversal
static int mxPathSum(Node root, ref int maxPathSum) {
// Base case: If the node is null, return 0
if (root == null) {
return 0;
}
// Recursively calculate the maximum sum from
// node to leaf for left and right subtrees
int mxLeft = mxPathSum(root.left, ref maxPathSum);
int mxRight = mxPathSum(root.right, ref maxPathSum);
// If both left and right children exist,
// update maxPathSum
if (root.left != null && root.right != null) {
// This is the sum of the left path,
// right path, and the node's data
int maxSumPathViaNode = mxLeft + mxRight + root.data;
// Update the maximum sum path between
// two leaves
maxPathSum = Math.Max(maxPathSum, maxSumPathViaNode);
// Return the maximum sum from the current
// node to a leaf
return root.data + Math.Max(mxLeft, mxRight);
}
// If only one child exists, return the sum from
// the node to leaf
return root.data +
(root.left != null ? mxLeft : mxRight);
}
// Function to return the maximum path
// sum between any two leaves in the binary tree
static int FindMaxSum(Node root) {
// Edge case: If the tree is empty,
// return 0
if (root == null) {
return 0;
}
int maxPathSum = int.MinValue;
// Call the helper function to
// compute the result
mxPathSum(root, ref maxPathSum);
return maxPathSum;
}
static void Main(string[] args) {
// Construct a sample binary tree
//
// 1
// / \
// -2 3
// / \ / \
// 8 -1 4 -5
Node root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(8);
root.left.right = new Node(-1);
root.right.left = new Node(4);
root.right.right = new Node(-5);
int result = FindMaxSum(root);
Console.WriteLine(result);
}
}
JavaScript
// JavaScript program to find maximum path
// sum between two leaves of a binary tree
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// mxPathSum function to calculate maximum path
// sum between two leaves and maximum sum from node
// to leaf in a single traversal
function mxPathSum(root) {
if (root === null) {
return 0;
}
const mxLeft = mxPathSum(root.left);
const mxRight = mxPathSum(root.right);
// If both left and right children exist,
// update maxPathSum
if (root.left !== null && root.right !== null) {
// This is the sum of the left path,
// right path, and the node's data
const maxSumPathViaNode = mxLeft + mxRight + root.data;
maxPathSum = Math.max(maxPathSum, maxSumPathViaNode);
// Return the maximum sum from the current
// node to a leaf
return root.data + Math.max(mxLeft, mxRight);
}
// If only one child exists, return the sum from
// the node to leaf
return root.data + (root.left ? mxLeft : mxRight);
}
// Function to return the maximum path sum between any
// two leaves in the binary tree
function findMaxSum(root) {
maxPathSum = Number.NEGATIVE_INFINITY;
mxPathSum(root);
return maxPathSum;
}
// Construct a sample binary tree
//
// 1
// / \
// -2 3
// / \ / \
// 8 -1 4 -5
const root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(8);
root.left.right = new Node(-1);
root.right.left = new Node(4);
root.right.right = new Node(-5);
const result = findMaxSum(root);
console.log(result);
Time complexity: O(n) where n is the number of nodes
Auxiliary Space: O(h), where h is height of tree.
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read