Open In App

Print all the paths from root, with a specified sum in Binary tree

Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ program to print all paths beginning with 
// root and sum as given sum 
#include<bits/stdc++.h> 
using namespace std; 
  
// A Tree node 
struct Node 
    int key; 
    struct Node *left, *right; 
}; 
  
// Utility function to create a new node 
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
  
    // add the current node's value 
    sum_so_far += curr_node->key; 
  
    // add the value to path 
    path.push_back(curr_node->key); 
  
    // print the required path 
    if (sum_so_far == sum ) 
    
        cout << "Path found: "
        for (int i=0; i<path.size(); i++) 
            cout << path[i] << " "
  
        cout << endl; 
    
  
    // if left child exists 
    if (curr_node->left != NULL) 
        printPathsUtil(curr_node->left, sum, sum_so_far, path); 
  
    // if right child exists 
    if (curr_node->right != NULL) 
        printPathsUtil(curr_node->right, sum, sum_so_far, path); 
  
  
    // Remove last element from path 
    // and move back to parent 
    path.pop_back(); 
  
// Wrapper over printPathsUtil 
void printPaths(Node *root, int sum) 
    vector<int> path; 
    printPathsUtil(root, sum, 0, path); 
  
// Driver program 
int main () 
    /* 10 
    /     \ 
    28     13 
        /     \ 
        14     15 
        / \     / \ 
    21 22 23 24*/
    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




// Java program to print all paths beginning
// with root and sum as given sum
import java.util.ArrayList;
  
class Graph{
  
// A Tree node
static class Node
{
    int key;
    Node left, right;
};
  
// Utility function to create a new node
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;
          
    // Add the current node's value
    sum_so_far += curr_node.key;
  
    // Add the value to path
    path.add(curr_node.key);
  
    // Print the required path
    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 left child exists
    if (curr_node.left != null)
        printPathsUtil(curr_node.left, sum,
                       sum_so_far, path);
  
    // If right child exists
    if (curr_node.right != null)
        printPathsUtil(curr_node.right, sum, 
                       sum_so_far, path);
  
    // Remove last element from path
    // and move back to parent
    path.remove(path.size() - 1);
}
  
// Wrapper over printPathsUtil
static void printPaths(Node root, int sum)
{
    ArrayList<Integer> path = new ArrayList<>();
    printPathsUtil(root, sum, 0, path);
}
  
// Driver code
public static void main(String[] args)
{
      
    /*    10 
       /     \ 
     28       13 
           /     \ 
         14       15 
        /   \     /  \ 
       21   22   23   24*/
    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);
}
}
  
// This code is contributed by sanjeev2552


Python3




# Python3 program to Print all the 
# paths from root, with a specified 
# sum in Binary tree 
      
# Binary Tree Node 
""" utility that allocates a newNode 
with the given key """
class newNode: 
  
    # Construct to create a newNode 
    def __init__(self, key): 
        self.key = key 
        self.left = None
        self.right = None
  
# This function prints all paths 
# that have sum k 
def printPathsUtil(curr_node, sum
                sum_so_far, path): 
  
    # empty node 
    if (not curr_node) : 
        return
    sum_so_far += curr_node.key 
      
    # add current node to the path 
    path.append(curr_node.key) 
  
    # print the required path 
    if (sum_so_far == sum ) : 
      
        print("Path found:", end = " "
        for i in range(len(path)): 
            print(path[i], end = " "
  
        print() 
      
    # if left child exists 
    if (curr_node.left != None) : 
        printPathsUtil(curr_node.left, sum
                    sum_so_far, path) 
  
    # if right child exists 
    if (curr_node.right != None) : 
        printPathsUtil(curr_node.right, sum
                    sum_so_far, path) 
  
    # Remove the current element 
    # from the path 
    path.pop(-1
  
# A wrapper over printKPathUtil() 
def printPaths(root, sum): 
  
    path = [] 
    printPathsUtil(root, sum, 0, path) 
  
# Driver Code 
if __name__ == '__main__'
  
    """ 10 
    /     \ 
    28     13 
        /     \ 
        14     15 
        / \     / \ 
    21 22 23 24"""
    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
  
# This code is contributed by 
# Shubham Singh(SHUBHAMSINGH10) 


C#




using System;
using System.Collections.Generic;
  
class Graph
{
    // A Tree node
    public class Node
    {
        public int key;
        public Node left, right;
    }
  
    // Utility function to create a new node
    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;
  
        // Add the current node's value
        sum_so_far += curr_node.key;
  
        // Add the value to path
        path.Add(curr_node.key);
  
        // Print the required path
        if (sum_so_far == sum)
        {
            Console.Write("Path found: ");
            for (int i = 0; i < path.Count; i++)
                Console.Write(path[i] + " ");
  
            Console.WriteLine();
        }
  
        // If left child exists
        if (curr_node.left != null)
            printPathsUtil(curr_node.left, sum,
                           sum_so_far, path);
  
        // If right child exists
        if (curr_node.right != null)
            printPathsUtil(curr_node.right, sum,
                           sum_so_far, path);
  
        // Remove last element from path
        // and move back to parent
        path.RemoveAt(path.Count - 1);
    }
  
    // Wrapper over printPathsUtil
    public static void printPaths(Node root, int sum)
    {
        List<int> path = new List<int>();
        printPathsUtil(root, sum, 0, path);
    }
  
    // Driver code
    public static void Main(string[] args)
    {
  
        /*    10 
           /     \ 
         28       13 
               /     \ 
             14       15 
            /   \     /  \ 
           21   22   23   24*/
        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);
    }
}
  
// This code is contributed by Potta Lokesh


Javascript




<script>
   
// JavaScript program to print all paths beginning
// with root and sum as given sum
  
// A Tree node
class Node
{
    constructor()
    {
        this.key = 0;
        this.left = null;
        this.right = null;
    }
};
  
// Utility function to create a new node
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;
          
    // Add the current node's value
    sum_so_far += curr_node.key;
  
    // Add the value to path
    path.push(curr_node.key);
  
    // Print the required path
    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 left child exists
    if (curr_node.left != null)
        printPathsUtil(curr_node.left, sum,
                       sum_so_far, path);
  
    // If right child exists
    if (curr_node.right != null)
        printPathsUtil(curr_node.right, sum, 
                       sum_so_far, path);
  
    // Remove last element from path
    // and move back to parent
    path.pop();
}
  
// Wrapper over printPathsUtil
function printPaths(root, sum)
{
    var path = [];
    printPathsUtil(root, sum, 0, path);
}
  
// Driver code
  
/*    10 
   /     \ 
 28       13 
       /     \ 
     14       15 
    /   \     /  \ 
   21   22   23   24*/
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>


Output

Path 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.

 



Last Updated : 12 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads