30 Day Risk-Free Guarantee:
100% money back if you're unsatisfied.
Book (308 Pages):
  • 150 Programming Interview Questions and Solutions
  • Five Proven Approaches to Solving Tough Algorithm Questions
  • Ten Mistakes Candidates Make -- And How to Avoid Them
  • Steps to Prepare for Behavioral and Technical Questions
  • Interview War Stories: A View from the Interviewer's Side
  • Book Preview and More Info

Video (One Hour):
  • Watch CareerCup's founder perform a totally unscripted technical interview of a candidate.
  • Overview of what interviewers look for in software engineering jobs.
  • Technical questions with white-boarding coding where the candidate does well - and struggles.
  • Interviewer reviews with what went well and poorly.
  • Video Preview and More Info

Resume Review (24 - 48hr)
  • Get your resume reviewed by a trained engineering interviewer. More Info
All Products / Services


Express Prep Package (Book)
$29.99 for e-book | $32.45 for paperback
Buy E-Book Buy on Amazon


Standard Prep Package (E-Book & Video)
Emailed Instantly | $39.99
Buy Standard

Elite Prep Package (E-Book, Video & Resume)
Emailed Instantly | $99.99
Buy Elite
 



Given a value and a binary search tree.
Print all the paths(if there exists more than one) which sum up to that value. It can be any path in the tree. It doesn't have to be from the root.

49


dingxiang on April 24, 2007 |Edit | Edit

void printPaths(struct node* node) {
int path[1000];

printPathsRecur(node, path, 0);
}

/*
Recursive helper function -- given a node, and an array containing
the path from the root node up to but not including this node,
print out all the root-leaf paths.
*/
void printPathsRecur(struct node* node, int path[], int pathLen) {
if (node==NULL) return;

// append this node to the path array
path[pathLen] = node->data;
pathLen++;

// it's a leaf, so print the path that led to here
if (node->left==NULL && node->right==NULL) {
printArray(path, pathLen);
}
else {
// otherwise try both subtrees
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
}
}

// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
int i;
for (i=0; i<len; i++) {
printf("%d ", ints[i]);
}
printf("\n");
}

vodangkhoa on April 24, 2007 |Edit | Edit

Hi dingxiang,

The solution you gave just print out all the paths from root to leaf. You should keep track of the sum and check it before you print out the path.

Anonymous on April 30, 2007 |Edit | Edit

How about a solution that explores the whole search space?

For each node in tree:
Explore(List<Node>, remaining_sum)

List<Node> stores path so far

Explore (List<Node>, remaining_sum)
Current_node = last_node_in_list
If coming from parent (i.e., last node in List is child of second-last node in List)
if (current_node->left_child exists)
Add to List: current_node->left_child
remaining_sum -= value(current_node->left_child)
// check_and_print
if (remaining_sum == 0)
print List
return
if (remaining_sum < 0)
return
Explore (List<Node>, remaining_sum)
// do similarly for right child

// do similarly if coming from bottom-left and bottom right
If coming from bottom-left
Explore (parent,remaining_sum)
Explore (right_child, remaining_sum)
If coming from bottom-right
Explore (parent,remaining_sum)
Explore (left_child, remaining_sum)

Michael on June 22, 2009 |Edit | Edit

With these types of questions, paths in binary-trees, there is almost always some confusion about what is meant by a 'path' in a binary tree. A path in a binary-tree is the sequence of edges between any two of its nodes, not just the path from the root to the leaves, which is just the height. By definition a tree is an undirected graph with 'simple paths' between any two of its nodes. A 'simple path' is a path which is a sequence of edges that doesn't use the same edge more than once. See ‘Discrete Mathematic and its Applications’ by Rosen pp 528-529.

Anonymous on April 30, 2007 |Edit | Edit

I forgot to put

 and 
and so indentation is bad. I'm retrying again:

How about a solution that explores the whole search space?

For each node in tree: Explore(List<Node>, remaining_sum)

List<Node> stores path so far

Explore (List<Node>, remaining_sum)
Current_node = last_node_in_list
If coming from parent (i.e., last node in List is child of second-last node in List)
if (current_node->left_child exists)
Add to List: current_node->left_child
remaining_sum -= value(current_node->left_child)
// check_and_print
if (remaining_sum == 0)
print List
return
if (remaining_sum < 0)
return
Explore (List<Node>, remaining_sum)
// do similalrly for right child

// do similarly if coming from bottom-left and bottom right
If coming from bottom-left
Explore (parent,remaining_sum)
Explore (right_child, remaining_sum)
If coming from bottom-right
Explore (parent,remaining_sum)
Explore (left_child, remaining_sum)

dingxiang on May 09, 2007 |Edit | Edit

I can change the solution to including the sum, but still my solution will be from the path. Any hints?

void printPaths(struct node* node) {
int path[1000];

printPathsRecur(node, path, 0, sum);
}

void printPathsRecur(struct node* node, int path[], int pathLen, int sum) {
if (node==NULL) return;

// append this node to the path array
path[pathLen] = node->data;
pathLen++;
sum=sum - node->data;

if (sum==0) {
printArray(path, pathLen);
}
else {
printPathsRecur(node->left, path, pathLen, sum-node->left.data);
printPathsRecur(node->right, path, pathLen, sum-node->right.data);
}
}

// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
int i;
for (i=0; i<len; i++) {
printf("%d ", ints[i]);
}
printf("\n");
}

vodangkhoa on May 10, 2007 |Edit | Edit

You need two more recursive calls to printPathsRecur where you don't subtract the sum. Something like this.

else {
printPathsRecur(node->left, path, pathLen, sum-node->left.data);
printPathsRecur(node->right, path, pathLen, sum-node->right.data);

printPathsRecur(node->left, path, pathLen, ORIGINAL_SUM);
printPathsRecur(node->right, path, pathLen, ORIGINAL_SUM);
}
ORIGINAL_SUM is the sum that was passed in at the beginning.

Ravi Kant Pandey on June 12, 2007 |Edit | Edit

last two recursive calls
printPathsRecur(node->left, path, pathLen, ORIGINAL_SUM);
printPathsRecur(node->right, path, pathLen, ORIGINAL_SUM);
will be called many(no of ancester+1) times for the same node

Den on May 23, 2007 |Edit | Edit

void findsum(node* head, int sum, int* buffer, int level)
{
if(*head==NULL)
return;

int temp = sum;
buffer[level] = head->data;
for(int i = level; i>=0;i--)
{
temp = temp - buffer[i];
if(temp==0)
print(buffer, level, i);
}
findsum(head->left, sum, buffer, left+1);
findsum(head->right, sum, buffer, left+1);
}

void print(int* buf, int start, int end)
{
for(int i = start;i<=end;i++)
{
printf(buffer[i]);
}
}

jj on August 22, 2007 |Edit | Edit

theres a type o , it should be level+1 and not left +1;

{
findsum(head->left, sum, buffer, level+1);
findsum(head->right, sum, buffer, level+1);
}

Anonymous on May 28, 2007 |Edit | Edit

From root node, DFS and calculate the sum value of path from root node to any left nodes and right nodes in tree.
Also, you can know the sum value of path from any node to its left children and right children.

To each node, calculate the sum of a left child path value and a right child path value, You can get the answer.

av on June 26, 2007 |Edit | Edit

void printPaths(struct node* node) {
int path[1000];

printPathsRecur(node, path, 0, sum);
}

void printPathsRecur(struct node* node, int path[], int pathLen, int sum) {
if (node==NULL) return;

// append this node to the path array
path[pathLen] = node->data;
pathLen++;
sum=sum - node->data;

if (sum==0) {
printArray(path, pathLen);
}
else {
printPathsRecur(node->left, path, pathLen, sum);
printPathsRecur(node->right, path, pathLen, sum);
}
}

// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
int i;
for (i=0; i<len; i++) {
printf("%d ", ints[i]);
}
printf("\n");
}

@mit on July 01, 2007 |Edit | Edit

hi thr... i'm giving this algorithm.... havnt checked it but i think i'll work...
It doesnt need any array to store the path or something...
It assumes the following structure...

struct node
{
struct node *left,*right,*parent;
int data;
};
typedef struct node *Node;

void PrintAllPaths(Node root,int currentSum, int totalSum)
{
if(root==NULL)return;

if(root->data==currentSum)
{
printPath(root,sum); //print the currently found path separately
}
else
{
printAllPaths(root->left, currentSum-root->data ,totalSum);
printAllPaths(root->left, currentSum-root->data ,totalSum);
}

/*But to cover the entire possibilities u must not return from here otherwise the solution paths starting from root->left or root->right will remain unexplored.
*/
printAllPaths(root->left, totalSum ,totalSum);
printAllPaths(root->right, totalSum ,totalSum);

return;
}

void printPath(Node root,int sum)
{
if(root->key==sum)
printf(" %d ",root->key);

else
printPath(root,sum-root->key);
printf(" %d ",root->key);

return;
}

@mit on July 01, 2007 |Edit | Edit

hi thr... i'm giving this algorithm.... havnt checked it but i think i'll work...
It doesnt need any array to store the path or something...
It assumes the following structure...

struct node
{
struct node *left,*right,*parent;
int data;
};
typedef struct node *Node;

void PrintAllPaths(Node root,int currentSum, int totalSum)
{
if(root==NULL)return;

if(root->data==currentSum)
{
printPath(root,sum); //print the currently found path separately
}
else
{
printAllPaths(root->left, currentSum-root->data ,totalSum);
printAllPaths(root->left, currentSum-root->data ,totalSum);
}

/*But to cover the entire possibilities u must not return from here otherwise the solution paths starting from root->left or root->right will remain unexplored.
*/
printAllPaths(root->left, totalSum ,totalSum);
printAllPaths(root->right, totalSum ,totalSum);

return;
}

void printPath(Node root,int sum)
{
if(root->key==sum)
printf(" %d ",root->key);

else
printPath(root,sum-root->key);
printf(" %d ",root->key);

return;
}

TheGreatOne on September 02, 2007 |Edit | Edit

Hi @mit,

I think your code is correct except the print routine. It should be :

void printPath(Node root,int sum)


if(root->key==sum)
printf(" %d ",root->key);

else
printPath(root->parent,sum-root->key);
printf(" %d ",root->key);

return;

Ram on September 30, 2007 |Edit | Edit

So I think this could work but the complexity of this little high...
say there are n nodes in the tree and log(n) is the height of the tree...then the leaf node would be checked log(n) times, the one above it for log(n)-1 times and so on...it could tend towards a log(n)!...while for large values of n, will perform badly.

tujl on July 02, 2007 |Edit | Edit


// This code tries to avoid doing the recursion twice...
void printPathSum(struct node* node, int totalSum) {
int path[1000];

printPathsRecur(node, path, 0, totalSum, 0, 0);
}

void printPathSumRecur(struct node* node, int path[], int pathLen, int totalSum, int curSum, int sumIdx0) {
if (node==NULL) return;

// append this node to the path array
path[pathLen] = node->data;
pathLen++;

if(curSum==totalSum)
printpath(path, sumIdx0, pathLen);

while(curSum>=totalSum)curSum-=path[sumIdx0++];

// otherwise try both subtrees
printPathSumRecur(node->left, path, pathLen, totalSum, curSum+node->data, sumIdx0);
printPathSumRecur(node->right, path, pathLen,totalSum, curSum+node->data, sumIdx0);
}

// Utility that prints out an array on a line.
void printArray(int ints[], int initidx, int len) {
int i;
for (i=initidx; i<len; i++) {
printf("%d ", ints[i]);
}
printf("\n");
}

Anonymous on July 02, 2007 |Edit | Edit

void PrintSumPaths(Node* n, int sum)
{
if(NULL == n)
return;

if(n->_left == NULL && n->_right == NULL && n->_data && sum == n->_data)
{
printf("Found the path\n");
}

if(n->_left)
{
PrintSumPaths(n->_left, sum);
PrintSumPaths(n->_left, sum - n->_data);
}

if(n->_right)
{
PrintSumPaths(n->_right, sum);
PrintSumPaths(n->_right, sum - n->_data);
}
}

Gabbar on July 29, 2007 |Edit | Edit


public void ExploreAllPaths(Tree root, int[] path, int pathLength, int remainingSum)
{
if (root == null)
return;

remainingSum -= root.Data;

if (remainingSum >= 0)
{
path[pathLength] = root.Data;
pathLength++;

if (remainingSum > 0)
{
ExploreAllPaths(root.Left, path, pathLength, remainingSum);
ExploreAllPaths(root.Right, path, pathLength, remainingSum);
}
else
{
PrintPath(path, pathLength);
}
}

ExploreAllPaths(root.Left, path, 0, Sum);
ExploreAllPaths(root.Right, path, 0, Sum);
}

AT on August 24, 2007 |Edit | Edit

If the paths can be from a node in left sub tree to any other node in right subtree lower down in tree excluding the root.. then convert the tree to a graph and then perform DF / BF traversal

Tangent on August 25, 2007 |Edit | Edit

For dingxiang/Khoa soln:
I think in recursive call just pass "sum" instead of sum-node.data as we have already done sum=sum-node.data

KDACE on October 18, 2007 |Edit | Edit

All solutions above are wrong....
Check with a sample tree:
1
2 3
4 5 6 7

If the desired sum was 8. then all above C codes print 1,2,4,5..Which is incorrect.
@mit's code does not even do that.. it will not print anything...
So the suggestion is whenever the condition root->null is true. It must return level-2.
This level - 2 + 1 will be the array index for the next element on right sub-tree. Thus it will now overwrite
number 4. Which is perfect. Now the nodes in the array will be: 1,2,5 making sum as 8.

Anonymous on October 21, 2007 |Edit | Edit

your input is even not a bst

Anonymous on February 08, 2008 |Edit | Edit

True we are talking about BST rember the invariant

Vel on October 27, 2007 |Edit | Edit

guys, could someone explain the complexity(time and space) of above code snippets ... i cant think of a solution better than O(n (logn)^2)..!
btw.. wats the order of finding a subsequence of given sum in an array of integers (+ve and -ve) ? is there a soln better than n^2 ?

joe di maggio on October 29, 2007 |Edit | Edit

i can think of an O(n) soln but the space complexity is O(n^2). Here's how- keep adding every new element to a new list as well as to existing list. so for example you traverse 1,2,3 you'll have 3 lists:

1 2 3
2 3
3

also keep a count of the running sum of each list. if it equals or goes beyond your target stop adding to that list.

as for finding a subsequence of given sum in an array of integers (+ve and -ve), you can repeat the above algorithm in that case too.

Nickname on November 03, 2007 |Edit | Edit

Can't DFS solve this problem right away?
What's wrong with using DFS to solve this problem ?

Time complexity for DFS is
O( | V | + | E | ) = O(b^d)

Chow Yun Fat on November 03, 2007 |Edit | Edit

Hi all,

if we can put traverse the binary tree into an array, we can solve it a lil bit faster.

traversal of a tree is o(n) into an array
printing path and summing them is o(n) , i believe that we can make good use of some of the properties of a binary tree 2^d - k and the range of k is the number of nodes @ level d.

and the algo can stop if each and every node's been visited at least once.

HOWEVER
i think the path and the sum can be returned during the traversal phrase
but the array makes printing a random path possible.

Chow Yun Fat.

nar on November 06, 2007 |Edit | Edit

Solution:
say the number is n.
Do an in-order traveral of the tree until we reach a node that is >= n-1, during in-order traversal, add value of each node into an array [maxlen = n].

Now start a while (true) loop.
start from array[0] and calculating the sum till sum = n. If during the loop, sum > n, reset sum = 0 and re-start summing from index 1 of the array... till all the elements of the array have been examined. Since we have to find all the paths, when sum = n, print out the elements of the array from starting index to the point where sum was found.

Key point is that paths in a tree have to be made of consecutive nodes and secondly in this case an in-order traveral will give us the nodes in sorted order.

too lazy to give pseudo code :p

Anonymous on November 28, 2007 |Edit | Edit

I cogitate this works
Run a BFS on the BST and see if the sum is <=0 if so then check all the paths in that sub tree
and keep on reducing the sum and if at any point the sum is zero print it..


void callPath(node *node,int sum){
int path[1000];
struct node* temp;
Queue q=new Queue();
if(node==NULL) return;
else
q.enqueue(node);

while(!q.isempty(){
temp=q.dequeue();
if(temp->data<=sum)
hasPath(temp,sum,path,0);
if(temp->left)
q.enqueue(temp->left);
if(temp->right)
q.enqueue(temp->right);
}
}

void hasPath(node* node,int sum,int[] path,int pathLen){
if(node==null) return;
else{
path[pathLen]=node->data;
pathLen++;
int sub=sum-node->data;
if(sub==0)
print(path,pathLen);
hasPath(node->left,sub,path,pathLen);
hasPath(node->right,sub,path,pathLen);

}
}

void print(int[] path,int pathLen){
for(int i=0;i<pathLen;i++)
print(pathLen[i]);
}

Vamsi on November 28, 2007 |Edit | Edit

Sorry I was not clear in the previous post..

Run a BFS on the BST and see if the sum is <= to the current node value if so check all the paths from the nodes
and recursively reduce the sum and at any point if we see that sum is zero print the path...

void callPath(node *node,int sum){
int path[1000];
struct node* temp;
Queue q=new Queue();
if(node==NULL) return;
else
q.enqueue(node);

while(!q.isempty(){
temp=q.dequeue();
if(temp->data<=sum)
hasPath(temp,sum,path,0);
if(temp->left)
q.enqueue(temp->left);
if(temp->right)
q.enqueue(temp->right);
}
}

void hasPath(node* node,int sum,int[] path,int pathLen){
if(node==null) return;
else{
path[pathLen]=node->data;
pathLen++;
int sub=sum-node->data;
if(sub==0)
print(path,pathLen);
else{
hasPath(node->left,sub,path,pathLen);
hasPath(node->right,sub,path,pathLen);
}
}
}

void print(int[] path,int pathLen){
for(int i=0;i<pathLen;i++)
print(pathLen[i]);
}

Anonymous on January 02, 2008 |Edit | Edit

My idea:

1. First of all, consider the core of this problem: it is asking for a continuous subset sum in an array, e.g.

0 1 2 3 4 5 6
8 1 5 2 4 3 7

we should be able to finish finding the subset in O(n) time. This can be done with augmentation every a[i] with a sum from a[0] to a[i], plus a hashtable containing all these sums. When we come to a[i], we can immediately know whether and where is the starting point of such a subset.

2. Then we can augment the tree nodes with the sum from the root to the current node. And then, perform DFS on the tree, and build the hashtable of the current path up to the current depth with O(1) per recursion. With the augmentation and the dynamic hashtable, this is essentially the same as 1. The whole algorithm should be able to finish in O(n).

Eric Cartman on January 10, 2008 |Edit | Edit

Guys,
First of all can there be more than one such path assuming the sum input is greater than the largest value in the tree (If it is lesser there is the trivial solution of the element itself, if it exists). I am guessing there is only one such path because of the nature of the BST. In which case it is possible to find that path in O(n) time (depth-first maybe).

Nikhil Agashe on January 14, 2008 |Edit | Edit

Hi Eric,

Consider a BST:
10
5 12
2 8 11 15

And the request is for sum = 15.
there are 2 paths: 10 - 5, 15.

I think your doubt should be cleared. Moreover, the problem does not indicate any condition on the sum requested, So it would complicate if we were to assume that it is greater, equal or smaller than the maximum element.

vairaghi on January 20, 2008 |Edit | Edit

This is my solution

 
public List<Path> findPaths(int value)
{
List <Path> candidatePaths = findPaths(root, value);
List <Path> paths = new ArrayList<Path>();
for(Path candidatePath:candidatePaths)
{
if(candidatePath.isComplete())
paths.add(candidatePath);
}
return paths;
}

public List <Path> findPaths(Node node, int value)
{
// this returns completed paths of value or incomplete paths of lesser value
if(node == null)
return null;

List <Path> paths = new ArrayList<Path>();
List <Path> leftPaths = null;
List <Path> rightPaths = null;

Path thisPath = new Path(node);
if(node.getValue() == value)
thisPath.setCompleted(true);
paths.add(thisPath);
if(node.getLeft() != null)
{
leftPaths = findPaths(node.getLeft(), value);

}
if(node.getRight() != null)
{
rightPaths = findPaths(node.getRight(), value);

}
if(leftPaths != null)
{

for(Path path:leftPaths)
{
path = (Path)path.clone();
if(path.isComplete())
{
paths.add(path);
continue;
}

path.insertRight(node);
if(path.getCount() == value)
path.setCompleted(true);
paths.add(path);


}
}
if(rightPaths != null)
{
for(Path path:rightPaths)
{
path = (Path)path.clone();
if(path.isComplete())
{
paths.add(path);
continue;
}

path.insertLeft(node);
if(path.getCount() == value)
path.setCompleted(true);
paths.add(path);
}
}

if(leftPaths != null && rightPaths != null)
{
for(Path path:leftPaths)
{
if(path.isComplete() != true)
{
for(Path rightPath:rightPaths)
{
if(rightPath.isComplete() != true)
{
if(path.getCount() + node.getValue() + rightPath.getCount() == value)
{
Path newPath = (Path)path.clone();
newPath.insertRight(node);
newPath = newPath.mergeRight(rightPath);
newPath.setCompleted(true);
paths.add(newPath);
}
}
}
}
}
}

return paths;
}

class Path implements Cloneable
{

private List <Node> nodeList;
private int count = 0;

boolean completed = false;
public Path()
{
nodeList = new ArrayList<Node>();
}

public Path(Node node)
{
nodeList = new ArrayList<Node>();
nodeList.add(node);
count += node.getValue();
}

public boolean isComplete()
{
return completed;
}

public void setCompleted(boolean completed)
{
this.completed = completed;
}

public Node getLeftNode()
{
if(nodeList.size() > 0)
return nodeList.get(0);
else
return null;
}

public Node getRightNode()
{
if(nodeList.size() > 0)
return nodeList.get(nodeList.size() - 1);
else
return null;

}

public void insertLeft(Node node)
{
nodeList.add(0, node);
count += node.getValue();
}

public void insertRight(Node node)
{
nodeList.add(nodeList.size() - 1, node);
count += node.getValue();
}

public int getCount()
{
return this.count;
}

public Object clone()
{
Path clone = new Path();
clone.nodeList.addAll(this.nodeList);
//Collections.copy(clone.nodeList, this.nodeList);
clone.count = this.count;
clone.setCompleted(this.completed);
return clone;
}

public Path mergeRight(Path rightPath)
{
Path newPath = (Path)this.clone();
newPath.nodeList.addAll(rightPath.nodeList);
newPath.count += rightPath.getCount();
return newPath;
}

}

dawninghu on February 02, 2008 |Edit | Edit

I believe this is the correct solution:

(it is not my credit, I just copy and paste from techinterview discussion.)
If you must start at the root, then the following will work (but can probably be improved upon):

Traverse your tree, changing it so that the value at each node changes to the value of it's parent node + it's original value. Thus the values are in this tree are the sum of the values in the unchanged tree from the root to the given point. If the value you currently have is the one you want, then add the path to this node to your list.

If you don't have to start at the root, then traverse your tree as before, but at each node replace its value with a list containing it's original value (head of the list), and its's original value summed with each element of it's parent's list (tail of list). Thus each node has a list of numbers, indicating the sum to that node starting from different ancestors, the number of ancestors required being the position in the list. If any of these values turn out to be the one you want, then store it in the list.

NB The above methods take no advantage of it being a binary search tree. A simple improvement is found by knowing that if your current value is too high and current node is non-negative, then you only need to search the left-hand branch. Similarly, if your current value is too low and the current node is non-positive, only search the right-hand tree. If you know in advance that the numbers are all non-negative or all non-positive, then you can stop searching altogther when you reach a sum that is too high/too low. (Stop at a value that is too extreme in the second algorithm).

If the paths must stop at a leaf, traverse the tree as above, but only store paths that sum to the correct value if they are a leaf node. Speed-ups still apply.

Swati on February 06, 2008 |Edit | Edit

Queue q;

void PrintPath(node *root,int sum)
{

if(root == NULL || sum < 0)
return;

CheckPathPresent(root,sum);
PrintPath(root->right,sum);
PrintPath(root->left,sum);
}

void CheckPathPathPresent(node *root,int sum)
{

if(root == NULL || sum < 0)
return;

int Diff = sum - root->Data;
q.Push(root->Data);
if(Diff == 0)
{
q.PrintQueue();
}
else
{
CheckPathPresent(root->left,Dif);
CheckPathPresent(root->right,Dif);
}
q.Pop(root->Data);
}

Anish on April 17, 2008 |Edit | Edit

@dawninghu,

Your solution looks correct.Its great to have such solution. But I feel that your solution has lottttt of memory requirement. At each node, you are storing almost n (let n is total number of nodes in tree) , you are consuming O(n2) space and that too , at each node, it wil take some good amount of time to traverse the array list.

My proposal is as follows:

Let the height of tree is k.
then create an k*k matrix. In this matrix, we will store the sum of distances from node at level 1...k to node at level 1..k .

0 1 2 3 4 5
1
2 0
3 0 0
4 0 0 0
5 0 0 0 0

so each element M(i,j) gives length of path from i to j.
so all lower triangle elements are 0.

now, traverse along the left most branch and update the matrix . it can be done very easily. If any value is the value we are looking for, then make a note of i and j values.
Now, go to one level up in the tree from the last node. So the last column and last row is invalid, but all others same. so, for nodes starting from this uplevel, add extra rows and columns to the matrix. start searching on the this upper level in the same way as we did earlier.

By doing this, we are not doing any extra calculations, i mean we are not calcuating any sum of lengths we already calculated, but we are reusing them by adding rows and colums of new nodes we find .

I think I didn't explain the algorithm in an easy understandable way. But try to get the essence in it.

asm on June 16, 2008 |Edit | Edit

brilliant idea, Anish ;)
looks like it really works: indeed one needs only one pass over the tree structure to find all
sums. Implementation is a bit quick-and-dirty but I hope quite understandable:


struct node {
int val;
node *left;
node *right;
};

int A[20][20]; // A[i][j] stores sum of path from level i to level j

int sum = 12; // the sum we are looking for

// j is the current level
void traverse(node *t, int j) {

if(t == 0)
return;

if(t->val == sum)
printf("%d\n", sum);
A[j][j] = t->val;

for(int i = 0; i < j; i++) {
A[i][j] = A[i][j-1] + t->val;

if(A[i][j] == sum) {
for(int k = j; k >= i; k--) {
int tmp = A[i][k];
if(k > i)
tmp -= A[i][k-1];
printf("%d ", tmp);
}
printf("\n");
}
}
traverse(t->left, j+1);
traverse(t->right, j+1);
}

main() {
traverse(head, 0);
}

creepingdog on April 25, 2008 |Edit | Edit

BST does not have to be directed, right? And has anybody mentioned the situation shown in the following example?

level node.data left_child.data right_child.data
0 20 7 21
1 7 3 9
1 21 null null
2 3 2 5
2 9 8 10
3 2 null null
3 5 null null
3 8 null null
3 10 null null

If I ask you to find path whose sum is 21, you should return two paths: 2->3->7->9 and 21

algooz on April 27, 2008 |Edit | Edit


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct node
{
int data;
struct node *left;
struct node *right;
}Node;
typedef struct queue
{
Node * cell;
struct queue *next;
}Queue;

void Enqueue(Queue **head, Node *temp)
{
Queue *current = *head;

Queue *newNode = (Queue *)malloc(sizeof(Queue));
newNode->cell = temp;
newNode->next = NULL;

if(NULL == *head)
{
*head = newNode;
}
else
{
while(NULL != current->next)
current = current->next;
current->next = newNode;
}
}
Queue * Dequeue(Queue **head)
{
Queue *temp = *head;
if(NULL == *head)
return NULL;
else
{
*head = (*head)->next;
}
return temp;
}

Node * newNode(int val);
Node * insertNode(Node *, int);
Node * buildBST(Node *);
void inorder(Node *root);
int lookUp(Node *root, int val);
int pathSum(Node *, int);
void printArray(int path[], int len);
void pathSum(Node *root, int path[], int pathlen, int sum);
void levelOrder(Node *root);
void hasSum(Node *root);

#define ORIG_SUM 8

int main()
{
Node *root = NULL;

//int path[100];

root = buildBST(root);
printf("\nInorder traversal is : \n");
inorder(root);
printf("\n\n");

//pathSum(root, path, 0, ORIG_SUM);
levelOrder(root);

return 0;
}
void levelOrder(Node *root)
{
Queue *head = NULL;
Enqueue(&head,root);

while(NULL != head)
{
Queue *temp = Dequeue(&head);
hasSum(temp->cell);
if(temp->cell->left != NULL)
{
Enqueue(&head,temp->cell->left);
}
if(temp->cell->right != NULL)
{
Enqueue(&head, temp->cell->right);
}
}
}
void hasSum(Node *root)
{
int path[100];
pathSum(root, path, 0, ORIG_SUM);
}
void pathSum(Node *root, int path[], int pathlen, int sum)
{
if(NULL == root)
return;
//append this node the current array
path[pathlen] = root->data;
++pathlen;
sum = sum - root->data;

if(0 == sum)
{
printArray(path, pathlen);
}
else
{
pathSum(root->left,path, pathlen,sum);
pathSum(root->right,path, pathlen,sum);
}

}
void printArray(int path[], int len)
{
int i=0;
for(i=0;i<len;i++)
{
printf("%d\t", path[i]);
}
printf("\n\n");
}
Node * newNode(int val)
{
Node *temp = (Node *)malloc(sizeof(Node));

if(NULL != temp)
{
temp->data = val;
temp->left = NULL;
temp->right = NULL;
}
else
exit(1);

return temp;
}
Node * insertNode(Node *root, int val)
{
if(NULL == root)
return newNode(val);
else
{
if(val < root->data)
root->left = insertNode(root->left, val);
else
root->right = insertNode(root->right, val);

return root;
}
}
Node * buildBST(Node * root)
{
int n;
int val;
int i;
int A[] = {5,3,7,2,4,6,8};

printf("\nHow many nodes in the tree ? ");
scanf("%d", &n);

srand(time(NULL));

for(i=0;i<n;i++)
{
/*val = rand()%98 + 1;
if(!lookUp(root, val))
{
root = insertNode(root, val);
}
else
{
printf("\nDuplicate value\n");
} */
root = insertNode(root, A[i]);
}
printf("\nInsertion Done !\n");

return root;
}
int lookUp(Node *root, int val)
{
if(NULL == root)
{
return 0;
}
else
{
if(val == root->data)
return 1;
else if(val < root->data)
return lookUp(root->left, val);
else
return lookUp(root->right, val);
}
}
void inorder(Node *root)
{
if(NULL == root)
return;
else
{
inorder(root->left);
printf("%d\t", root->data);
inorder(root->right);
}
}

Anonymous on May 20, 2008 |Edit | Edit


std::vector< std::vector<int> > pathToNum(bt_t* root , int num)
{

std::vector< std::vector<int> >resVec;
std::vector<int> tempVec;

if(!root){
return resVec;
}

std::stack< bt_t* > nst;
std::stack<int> sst;
std::stack< std::vector<int> > vst;

nst.push(root);
sst.push(num-root->data);

tempVec.push_back(root->data);
vst.push(tempVec);

while(!nst.empty())
{
bt_t* cur = nst.top();
nst.pop();

int sum = sst.top();
sst.pop();

std::vector<int> tempVec = vst.top();
vst.pop();

int a = tempVec.size();

if(sum<0){
while(sum<0){
if(!tempVec.empty()){
sum+= tempVec[0];
tempVec.erase(tempVec.begin());
}
else
sum = num;
}
}

if(sum==0)
{
if(tempVec.size()>1)
{
resVec.push_back(tempVec);
sum+= tempVec[0];
tempVec.erase(tempVec.begin());
}
}

if(cur->right){
nst.push(cur->right);
sst.push(sum-cur->right->data);
tempVec.push_back(cur->right->data);
vst.push(tempVec);
tempVec.pop_back();
}

if(cur->left){
nst.push(cur->left);
sst.push(sum-cur->left->data);
tempVec.push_back(cur->left->data);
vst.push(tempVec);
tempVec.pop_back();
}
}

return resVec;
}

XYZ on September 10, 2008 |Edit | Edit

No extra space is needed.
Tested on Visual Studio.

<<
bool find(Node* node, int sum)
{
if (!node)
return false;
else if (sum-node->value==0){
cout<<node->value;
return true;
}
else{
bool found=false;
if (find(node->left, sum-node->value)){
cout<<node->value;
found=true;
}
if(find(node->right, sum-node->value)){
cout<<node->value;
found=true;
}
return found;
}
}

void traverse(Node* node, int sum){
if (!node)
return ;
find(node, sum);
traverse(node->left, sum);
traverse(node->right, sum);
}

int main(){
traverse(root, 100);
}

>>

Laks on September 23, 2008 |Edit | Edit


package com.dale.topcoders;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class TreeWithParent {

private class node {
int data;
node left;
node right;
node parent;
}

static node root;

public void insertNode(int data) {
if (root == null) {
root = new node();
root.data = data;
root.left = null;
root.right = null;
root.parent = null;
return;
}
node cur = root;
if (cur.left != null) {
while (cur.left != null && cur.data > data) {
cur = cur.left;
}
}

if (cur.right != null) {
while (cur.right != null && cur.data < data) {
cur = cur.left;
}
}
node temp = new node();
temp.data = data;
temp.left = null;
temp.right = null;

if (data > cur.data) {
cur.right = temp;
} else {
cur.left = temp;
}
temp.parent = cur;
}

private void bfs() {
Queue<node> q = new ArrayBlockingQueue<node>(20);
node cur = root;
if (root == null) {
System.out.println("Empty Graph!");
return;
}
q.add(cur);
while (q.isEmpty() == false) {
node top = q.remove();
if (top != null) {
System.out.print(" Q : " + top.data);
if (top.parent != null)
System.out.print(" and its parent is " + top.parent.data);
System.out.println("");
if (top.left != null) {
q.add(top.left);
}
if (top.right != null) {
q.add(top.right);
}
}
}
}

public void printAllPaths(node cur, int curSum, int totalSum) {
if (cur == null) {
System.out.println("Empty List ! Cannot Print");
return;
}

if (cur.data == curSum) {
System.out.println("Found!");
printPath(cur, totalSum);
} else {
if (cur.left != null)
printAllPaths(cur.left, curSum - cur.data, totalSum);
if (cur.right != null)
printAllPaths(cur.right, curSum - cur.data, totalSum);
}
if (cur.left != null)
printAllPaths(cur.left, curSum - cur.data, totalSum);
if (cur.right != null)
printAllPaths(cur.right, curSum - cur.data, totalSum);
}

private void printPath(node cur, int sum) {
if (cur != null) {
if (cur.data == sum) {
System.out.println(" " + cur.data);
} else {
printPath(cur.parent, sum - cur.data);
}
System.out.println(" " + cur.data);
return;
}
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

TreeWithParent tree = new TreeWithParent();
tree.insertNode(5);
tree.insertNode(2);
tree.insertNode(7);
tree.insertNode(1);
tree.insertNode(3);
tree.insertNode(9);
tree.bfs();
node cur = root;
tree.printAllPaths(cur, 12, 12);
}

}

winia on October 31, 2008 |Edit | Edit

void PrintPath(t* root, int* a, int start, int end, int ori_sum)
//a[] is an predefined empty array, initial value for start and end is 0
{
if(!root) return;
a[end++]=root->val;
for(int i=start;i<end;i++)
sum+=a[i];
if(sum>=ori_sum)
{
if(sum==ori_sum)
{
for(int i=start;i<end;i++)
cout<<a[i];
}
start++;
}
PrintPath(root->left,int* a,int start, int end,int val);
PrintPath(root->right,int* a,int start, int end,int val);
}

nchikkam on December 30, 2008 |Edit | Edit

bool.find_sum(node*.root,.int.sum,.int*.a,.int.n){
..if.(!root)
......return.false;
..a[n].=.root->n;
..++n;
..if.(sum.-.root->n==0){
......for(int.i=0;i<n;++i)
..........cout.<<.a[i]<<.".";
......return.true;
..}else{
......if.(find_sum(root->left,.sum-root->n,.a,.n)){
..........return.true;
......}
......if(find_sum(root->right,.sum-root->n,.a,.n)){
..........return.true;
......}
......return.false;
..}
}

void.traverse_sum(node*.root,.int.sum){
..if.(!root)
......return.;
..int.a[100];
..int.l.=.100;
..find_sum(root,.sum,.a,.0);
..cout.<<."\n";
..traverse_sum(root->left,.sum);
..traverse_sum(root->right,.sum);
}

Dumbo on February 22, 2009 |Edit | Edit

Brute force method: can be done by modifying tree traversal method to include variable arguments containing the key values from the root to the parent.

At the current node, copy the variable arguments to an array (or a linked list) check whether any contiguous subsequence sum of numbers from the root the current node adds up to the given number.

Checking whether any contigious subsequence sum adds up to the given number can be solved in O(n) using the following algo.

maintain two indices startIndex and endIndex. Initially they both point to the beginning to of the array. Take a variable runningSum and initialise it to 0.

while (runningSum != givenSum && endIndex < length(arr))
{
if (runningSum < givenNumber) runningSum += arr[endIndex++];
else if (runningSum > givenNumber) runningSum == arr[startIndex--];
}

if (endIndex >= length(arr))
return notfound
else
print startIndex, endIndex.

Anonymous on February 10, 2010 |Edit | Edit

PrintPath(root, sum, 0, 0, list, listOfList);
void PrintPath(node root,int remains,int start, int end, List<int> list, List<List<int>> listOfList)
{
if(root == null)
return;

int tempStart = start;
while(root.data > remains && tempStart != end)
{
remains = remains + list[0];
tempStart++;

}

if(root.data == remains)
{
List<int> temp = DeepCopy(list, tempStart, end);
listOfList.Add(temp);
}

if(root.data > remains)
return;

end = end + 1;
remains = remains - root.data;
list.Add(root.data);
PrintPath(root.left,tempStart, end, remains, list, listOfList);
PrintPath(root.right,tempStart, end, remains, list, listOfList);
list.Remove(list.Count-1);
}
Sum: 21,11,6

10
/ \
5 11
/ \
4 6
/
2
Sum:5
5
/
4
/
1

susanta on July 25, 2010 |Edit | Edit

I think one needs to traverse the whole tree and search each sub-tree at every node for the sum. so complexity is n log n.

Add a Text Comment | Add Runnable Code
Name:
Comment:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.








Amazon (1033)Bloomberg LP (403)Qualcomm (117)Adobe (88)Goldman Sachs (78)NetApp (49)IBM (43)Morgan Stanley (33)CapitalIQ (30)Sophos (25)Achieve Internet (23)Electronic Arts (19)Motorola (18)Research In Motion (17)Flipkart (16)
Microsoft (867)Google (141)NVIDIA (98)Yahoo (82)Epic Systems (69)Expedia (47)VMWare Inc (43)Apple (32)Cisco Systems (28)Facebook (23)Infosys (22)Agilent Technologies (19)Sage Software (17)Deshaw Inc (16)FlexTrade (15)
More Companies »
Software Engineer / Dev... (1062)Financial Software Deve... (170)Testing / Quality Assur... (56)Analyst (35)Virus Researcher (25)Field Sales (15)Developer Program Engin... (9)Front-end Software Engi... (6)MyJoB (5)area sales manager (4)Assistant (3)Cabin crew (2)Accountant (1)personnel (1)Intern (1)
Software Engineer in Te... (288)Program Manager (65)Development Support Eng... (47)INTERN(MSIDC) (28)Web Developer (18)System Administrator (10)Consultant (10)Production Engineer (5)Associate Technology L2 (5)AcquireKnowledge (4)Product Security Engine... (3)Solutions Architect (2)Gamer (1)mts (1)Fresh graduate interview (0)
More Job Titles »
Algorithm (1073)Terminology & Trivia (294)C (166)Object Oriented Design (159)Java (121)Testing (114)Arrays (101)Operating System (78)Database (70)Linked List (62)String Manipulation (56)Networking / Web / Inte... (44)Threads (36)Linux Kernel (33)PHP (22)
Coding (511)C++ (204)Behavioral (159)Data Structures (155)Experience (116)Brain Teasers (111)Computer Architecture &... (79)General Questions and C... (73)Trees and Graphs (69)Math & Computation (57)Application / UI Design (45)Ideas (38)System Design (35)Puzzles (30)Bit Manipulation (20)
More Topics »
CareerCup Official Interview Book Daily Questions Requests for Help Mock Interviews Video for Cracking the Coding Interview Job Placement Service CareerCup Blog
My Profile Edit Profile & Email Settings Sign Out