Given the root of a binary treeand an integer k, Count the number of paths in the tree such that the sum of the nodes in each path equals k. A path can start from any node and end at any node and must be downward only. Note: The nodes can have negativevalues.
[Naive Approach] By Exploring All Possible Paths - O(n2) Time and O(h) Space
The simplest approach to solve this problem is that, for each node in the tree, we consider it as the starting point of a path and explore all possible paths that go downward from this node. We calculate the sum of each path and check if it equals k.
C++
#include<iostream>#include<vector>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intk){data=k;left=nullptr;right=nullptr;}};// Function to count paths with// sum k starting from the given nodeintcountPathsFromNode(Node*node,intk,intcurrentSum){if(node==nullptr)return0;intpathCount=0;currentSum+=node->data;if(currentSum==k)pathCount++;// Recur for the left and right subtreepathCount+=countPathsFromNode(node->left,k,currentSum);pathCount+=countPathsFromNode(node->right,k,currentSum);returnpathCount;}// Function to count all paths // that sum to k in the binary treeintcountAllPaths(Node*root,intk){if(root==nullptr)return0;// Count all paths starting from the current nodeintres=countPathsFromNode(root,k,0);// Recursive for the left and right subtreeres+=countAllPaths(root->left,k);res+=countAllPaths(root->right,k);returnres;}intmain(){// Create a sample tree:// 8// / \ // 4 5// / \ \ // 3 2 2// / \ \ // 3 -2 1Node*root=newNode(8);root->left=newNode(4);root->right=newNode(5);root->left->left=newNode(3);root->left->right=newNode(2);root->right->right=newNode(2);root->left->left->left=newNode(3);root->left->left->right=newNode(-2);root->left->right->right=newNode(1);intk=7;cout<<countAllPaths(root,k)<<endl;return0;}
Java
// Node StructureclassNode{intdata;Nodeleft,right;Node(intk){data=k;left=null;right=null;}}classGfG{// Function to count paths with// sum k starting from the given nodestaticintcountPathsFromNode(Nodenode,intk,intcurrentSum){if(node==null)return0;intpathCount=0;currentSum+=node.data;if(currentSum==k)pathCount++;// Recur for the left and right subtreepathCount+=countPathsFromNode(node.left,k,currentSum);pathCount+=countPathsFromNode(node.right,k,currentSum);returnpathCount;}// Function to count all paths // that sum to k in the binary treestaticintcountAllPaths(Noderoot,intk){if(root==null)return0;// Count all paths starting from the current nodeintres=countPathsFromNode(root,k,0);// Recur for the left and right subtreeres+=countAllPaths(root.left,k);res+=countAllPaths(root.right,k);returnres;}publicstaticvoidmain(String[]args){// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1Noderoot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);intk=7;System.out.println(countAllPaths(root,k));}}
Python
# Node StructureclassNode:def__init__(self,k):self.data=kself.left=Noneself.right=None# Function to count paths with # sum k starting from the given nodedefcountPathsFromNode(node,k,currentSum):ifnodeisNone:return0pathCount=0currentSum+=node.dataifcurrentSum==k:pathCount+=1# Recur for the left and right subtreepathCount+=countPathsFromNode(node.left,k,currentSum)pathCount+=countPathsFromNode(node.right,k,currentSum)returnpathCount# Function to count all paths # that sum to k in the binary treedefcountAllPaths(root,k):ifrootisNone:return0# Count all paths starting from the current noderes=countPathsFromNode(root,k,0)# Recur for the left and right subtreeres+=countAllPaths(root.left,k)res+=countAllPaths(root.right,k)returnresif__name__=="__main__":# Create a sample tree:# 8# / \# 4 5# / \ \# 3 2 2# / \ \# 3 -2 1root=Node(8)root.left=Node(4)root.right=Node(5)root.left.left=Node(3)root.left.right=Node(2)root.right.right=Node(2)root.left.left.left=Node(3)root.left.left.right=Node(-2)root.left.right.right=Node(1)k=7print(countAllPaths(root,k))
C#
usingSystem;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intk){data=k;left=null;right=null;}}classGFG{// Function to count paths with // sum k starting from the given nodestaticintcountPathsFromNode(Nodenode,intk,intcurrentSum){if(node==null)return0;intpathCount=0;currentSum+=node.data;if(currentSum==k)pathCount++;// Recur for the left and right subtreepathCount+=countPathsFromNode(node.left,k,currentSum);pathCount+=countPathsFromNode(node.right,k,currentSum);returnpathCount;}// Function to count all paths// that sum to k in the binary treestaticintcountAllPaths(Noderoot,intk){if(root==null)return0;// Count all paths starting from the current nodeintres=countPathsFromNode(root,k,0);// Recur for the left and right subtreeres+=countAllPaths(root.left,k);res+=countAllPaths(root.right,k);returnres;}staticvoidMain(string[]args){// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1Noderoot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);intk=7;Console.WriteLine(countAllPaths(root,k));}}
JavaScript
// Node StructureclassNode{constructor(k){this.data=k;this.left=null;this.right=null;}}// Function to count paths with // sum k starting from the given nodefunctioncountPathsFromNode(node,k,currentSum){if(node===null)return0;letpathCount=0;currentSum+=node.data;if(currentSum===k)pathCount++;// Recur for the left and right subtreepathCount+=countPathsFromNode(node.left,k,currentSum);pathCount+=countPathsFromNode(node.right,k,currentSum);returnpathCount;}// Function to count all paths // that sum to k in the binary treefunctioncountAllPaths(root,k){if(root===null)return0;// Count all paths starting from the current nodeletres=countPathsFromNode(root,k,0);// Recur for the left and right subtreeres+=countAllPaths(root.left,k);res+=countAllPaths(root.right,k);returnres;}// Driver Code// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1constroot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);constk=7;console.log(countAllPaths(root,k));
Output
3
[Expected Approach] Using Prefix Sum Technique - O(n) Time and O(n) Space
We can use prefix sums with a hashmap to efficiently track the sum of paths in the binary tree. The prefix sum up to a node is the sum of all node values from the root to that node.
We traverse the tree using recursion and by storing the prefix sums of current path from root in a hashmap, we can quickly find if there are any sub-paths that sum to the target value k by checking the difference between the current prefix sum and k.
If the difference (current prefix sum - k) exists in the hashmap, it means there exists one or more paths, ending at the current node, that sums to k so we increment our count accordingly.
C++
#include<iostream>#include<vector>#include<unordered_map>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};intcountPathsUtil(Node*node,intk,intcurrSum,unordered_map<int,int>&prefSums){if(node==nullptr)return0;intpathCount=0;currSum+=node->data;if(currSum==k)pathCount++;// The count of (curr_sum â k) gives the number // of paths with sum k up to the current nodepathCount+=prefSums[currSum-k];// Add the current sum into the hashmapprefSums[currSum]++;pathCount+=countPathsUtil(node->left,k,currSum,prefSums);pathCount+=countPathsUtil(node->right,k,currSum,prefSums);// Remove the current sum from the hashmapprefSums[currSum]--;returnpathCount;}intcountAllPaths(Node*root,intk){unordered_map<int,int>prefSums;returncountPathsUtil(root,k,0,prefSums);}intmain(){// Create a sample tree:// 8// / \ // 4 5// / \ \ // 3 2 2// / \ \ // 3 -2 1Node*root=newNode(8);root->left=newNode(4);root->right=newNode(5);root->left->left=newNode(3);root->left->right=newNode(2);root->right->right=newNode(2);root->left->left->left=newNode(3);root->left->left->right=newNode(-2);root->left->right->right=newNode(1);intk=7;cout<<countAllPaths(root,k)<<endl;return0;}
Java
importjava.util.HashMap;// Node StructureclassNode{intdata;Nodeleft,right;Node(intval){data=val;left=null;right=null;}}classGFG{staticintcountPathsUtil(Nodenode,intk,intcurrSum,HashMap<Integer,Integer>prefSums){if(node==null)return0;intpathCount=0;currSum+=node.data;if(currSum==k)pathCount++;// The count of (curr_sum â k) gives the number // of paths with sum k up to the current nodepathCount+=prefSums.getOrDefault(currSum-k,0);// Add the current sum into the hashmapprefSums.put(currSum,prefSums.getOrDefault(currSum,0)+1);pathCount+=countPathsUtil(node.left,k,currSum,prefSums);pathCount+=countPathsUtil(node.right,k,currSum,prefSums);// Remove the current sum from the hashmapprefSums.put(currSum,prefSums.get(currSum)-1);returnpathCount;}staticintcountAllPaths(Noderoot,intk){HashMap<Integer,Integer>prefSums=newHashMap<>();returncountPathsUtil(root,k,0,prefSums);}publicstaticvoidmain(String[]args){// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1Noderoot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);intk=7;System.out.println(countAllPaths(root,k));}}
Python
# Node StructureclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=NonedefcountPathsUtil(node,k,currSum,prefSums):ifnodeisNone:return0pathCount=0currSum+=node.dataifcurrSum==k:pathCount+=1# The count of (curr_sum â k) gives the number # of paths with sum k up to the current nodepathCount+=prefSums.get(currSum-k,0)# Add the current sum into the hashmapprefSums[currSum]=prefSums.get(currSum,0)+1pathCount+=countPathsUtil(node.left,k,currSum,prefSums)pathCount+=countPathsUtil(node.right,k,currSum,prefSums)# Remove the current sum from the hashmapprefSums[currSum]-=1returnpathCountdefcountAllPaths(root,k):prefSums={}returncountPathsUtil(root,k,0,prefSums)if__name__=="__main__":# Create a sample tree:# 8# / \# 4 5# / \ \# 3 2 2# / \ \# 3 -2 1root=Node(8)root.left=Node(4)root.right=Node(5)root.left.left=Node(3)root.left.right=Node(2)root.right.right=Node(2)root.left.left.left=Node(3)root.left.left.right=Node(-2)root.left.right.right=Node(1)k=7print(countAllPaths(root,k))
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=null;right=null;}}classGFG{staticintcountPathsUtil(Nodenode,intk,intcurrSum,Dictionary<int,int>prefSums){if(node==null)return0;intpathCount=0;currSum+=node.data;if(currSum==k)pathCount++;// The count of (curr_sum â k) gives the number // of paths with sum k up to the current nodeif(prefSums.ContainsKey(currSum-k))pathCount+=prefSums[currSum-k];// Add the current sum into the hashmapif(!prefSums.ContainsKey(currSum))prefSums[currSum]=0;prefSums[currSum]++;pathCount+=countPathsUtil(node.left,k,currSum,prefSums);pathCount+=countPathsUtil(node.right,k,currSum,prefSums);// Remove the current sum from the hashmapprefSums[currSum]--;returnpathCount;}staticintcountAllPaths(Noderoot,intk){varprefSums=newDictionary<int,int>();returncountPathsUtil(root,k,0,prefSums);}staticvoidMain(){// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1Noderoot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);intk=7;Console.WriteLine(countAllPaths(root,k));}}
JavaScript
// Node StructureclassNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functioncountPathsUtil(node,k,currSum,prefSums){if(node===null)return0;letpathCount=0;currSum+=node.data;if(currSum===k)pathCount++;// The count of (curr_sum â k) gives the number // of paths with sum k up to the current nodepathCount+=prefSums[currSum-k]||0;// Add the current sum into the hashmapprefSums[currSum]=(prefSums[currSum]||0)+1;pathCount+=countPathsUtil(node.left,k,currSum,prefSums);pathCount+=countPathsUtil(node.right,k,currSum,prefSums);// Remove the current sum from the hashmapprefSums[currSum]--;returnpathCount;}functioncountAllPaths(root,k){constprefSums={};returncountPathsUtil(root,k,0,prefSums);}// Driver Code// Create a sample tree:// 8// / \// 4 5// / \ \// 3 2 2// / \ \// 3 -2 1constroot=newNode(8);root.left=newNode(4);root.right=newNode(5);root.left.left=newNode(3);root.left.right=newNode(2);root.right.right=newNode(2);root.left.left.left=newNode(3);root.left.left.right=newNode(-2);root.left.right.right=newNode(1);constk=7;console.log(countAllPaths(root,k));