Given a Binary tree and a sum S, print all the paths, starting from root, that sums upto the given sum.
Note that this problem is different from root to leaf paths. Here path doesn’t need to end on a leaf node.
Examples:
Input :
Input : sum = 8,
Root of tree
1
/ \
20 3
/ \
4 15
/ \ / \
6 7 8 9
Output :
Path: 1 3 4
Input : sum = 38,
Root of tree
10
/ \
28 13
/ \
14 15
/ \ / \
21 22 23 24
Output : Path found: 10 28
Path found: 10 13 15
For this problem, preorder traversal is best suited as we have to add up a key value as we land on that node.
We start from the root and start traversing by preorder traversal, adding key value to the sum_so_far and checking whether it is equal to the required sum.
Also, as tree node doesn’t have a pointer pointing to its parent, we have to explicitly save from where we have moved. We use a vector path to store the path for this.
Every node in this path contributes to the sum_so_far.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int key;
struct Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
void printPathsUtil(Node* curr_node, int sum,
int sum_so_far, vector< int > &path)
{
if (curr_node == NULL)
return ;
sum_so_far += curr_node->key;
path.push_back(curr_node->key);
if (sum_so_far == sum )
{
cout << "Path found: " ;
for ( int i=0; i<path.size(); i++)
cout << path[i] << " " ;
cout << endl;
}
if (curr_node->left != NULL)
printPathsUtil(curr_node->left, sum, sum_so_far, path);
if (curr_node->right != NULL)
printPathsUtil(curr_node->right, sum, sum_so_far, path);
path.pop_back();
}
void printPaths(Node *root, int sum)
{
vector< int > path;
printPathsUtil(root, sum, 0, path);
}
int main ()
{
Node *root = newNode(10);
root->left = newNode(28);
root->right = newNode(13);
root->right->left = newNode(14);
root->right->right = newNode(15);
root->right->left->left = newNode(21);
root->right->left->right = newNode(22);
root->right->right->left = newNode(23);
root->right->right->right = newNode(24);
int sum = 38;
printPaths(root, sum);
return 0;
}
|
Java
import java.util.ArrayList;
class Graph{
static class Node
{
int key;
Node left, right;
};
static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = temp.right = null ;
return (temp);
}
static void printPathsUtil(Node curr_node, int sum,
int sum_so_far,
ArrayList<Integer> path)
{
if (curr_node == null )
return ;
sum_so_far += curr_node.key;
path.add(curr_node.key);
if (sum_so_far == sum)
{
System.out.print( "Path found: " );
for ( int i = 0 ; i < path.size(); i++)
System.out.print(path.get(i) + " " );
System.out.println();
}
if (curr_node.left != null )
printPathsUtil(curr_node.left, sum,
sum_so_far, path);
if (curr_node.right != null )
printPathsUtil(curr_node.right, sum,
sum_so_far, path);
path.remove(path.size() - 1 );
}
static void printPaths(Node root, int sum)
{
ArrayList<Integer> path = new ArrayList<>();
printPathsUtil(root, sum, 0 , path);
}
public static void main(String[] args)
{
Node root = newNode( 10 );
root.left = newNode( 28 );
root.right = newNode( 13 );
root.right.left = newNode( 14 );
root.right.right = newNode( 15 );
root.right.left.left = newNode( 21 );
root.right.left.right = newNode( 22 );
root.right.right.left = newNode( 23 );
root.right.right.right = newNode( 24 );
int sum = 38 ;
printPaths(root, sum);
}
}
|
Python3
class newNode:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def printPathsUtil(curr_node, sum ,
sum_so_far, path):
if ( not curr_node) :
return
sum_so_far + = curr_node.key
path.append(curr_node.key)
if (sum_so_far = = sum ) :
print ( "Path found:" , end = " " )
for i in range ( len (path)):
print (path[i], end = " " )
print ()
if (curr_node.left ! = None ) :
printPathsUtil(curr_node.left, sum ,
sum_so_far, path)
if (curr_node.right ! = None ) :
printPathsUtil(curr_node.right, sum ,
sum_so_far, path)
path.pop( - 1 )
def printPaths(root, sum ):
path = []
printPathsUtil(root, sum , 0 , path)
if __name__ = = '__main__' :
root = newNode( 10 )
root.left = newNode( 28 )
root.right = newNode( 13 )
root.right.left = newNode( 14 )
root.right.right = newNode( 15 )
root.right.left.left = newNode( 21 )
root.right.left.right = newNode( 22 )
root.right.right.left = newNode( 23 )
root.right.right.right = newNode( 24 )
sum = 38
printPaths(root, sum )
|
C#
using System;
using System.Collections.Generic;
class Graph
{
public class Node
{
public int key;
public Node left, right;
}
public static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = temp.right = null ;
return (temp);
}
public static void printPathsUtil(Node curr_node, int sum,
int sum_so_far,
List< int > path)
{
if (curr_node == null )
return ;
sum_so_far += curr_node.key;
path.Add(curr_node.key);
if (sum_so_far == sum)
{
Console.Write( "Path found: " );
for ( int i = 0; i < path.Count; i++)
Console.Write(path[i] + " " );
Console.WriteLine();
}
if (curr_node.left != null )
printPathsUtil(curr_node.left, sum,
sum_so_far, path);
if (curr_node.right != null )
printPathsUtil(curr_node.right, sum,
sum_so_far, path);
path.RemoveAt(path.Count - 1);
}
public static void printPaths(Node root, int sum)
{
List< int > path = new List< int >();
printPathsUtil(root, sum, 0, path);
}
public static void Main( string [] args)
{
Node root = newNode(10);
root.left = newNode(28);
root.right = newNode(13);
root.right.left = newNode(14);
root.right.right = newNode(15);
root.right.left.left = newNode(21);
root.right.left.right = newNode(22);
root.right.right.left = newNode(23);
root.right.right.right = newNode(24);
int sum = 38;
printPaths(root, sum);
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
};
function newNode(key)
{
var temp = new Node();
temp.key = key;
temp.left = temp.right = null ;
return (temp);
}
function printPathsUtil(curr_node, sum, sum_so_far, path)
{
if (curr_node == null )
return ;
sum_so_far += curr_node.key;
path.push(curr_node.key);
if (sum_so_far == sum)
{
document.write( "Path found: " );
for ( var i = 0; i < path.length; i++)
document.write(path[i] + " " );
document.write( "<br>" );
}
if (curr_node.left != null )
printPathsUtil(curr_node.left, sum,
sum_so_far, path);
if (curr_node.right != null )
printPathsUtil(curr_node.right, sum,
sum_so_far, path);
path.pop();
}
function printPaths(root, sum)
{
var path = [];
printPathsUtil(root, sum, 0, path);
}
var root = newNode(10);
root.left = newNode(28);
root.right = newNode(13);
root.right.left = newNode(14);
root.right.right = newNode(15);
root.right.left.left = newNode(21);
root.right.left.right = newNode(22);
root.right.right.left = newNode(23);
root.right.right.right = newNode(24);
var sum = 38;
printPaths(root, sum);
</script>
|
OutputPath found: 10 28
Path found: 10 13 15
Time Complexity: O(N^2), in the worst case, where N is the number of nodes in the tree. This is because we potentially traverse all nodes in the tree, and for each leaf node, we check the sum of the path, which takes O(N) time in the worst case.
Auxiliary Space: O(h), where h is the height of the binary tree. This is because the maximum amount of space used by the algorithm at any given time is the size of the path vector, which is at most equal to the height of the binary tree. This is because the path vector is only added to when we are traversing down the tree, and its size is reduced back to 0 when we are traversing back up the tree. Therefore, the space used by the algorithm is proportional to the height of the tree.
This article is contributed by Shubham Gupta. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.