Interview Question


Country: United States




Comment hidden because of low score. Click to expand.
5
of 5 vote

Recursively calculate the sum

int maxsum(Node *root)
{
if (root == NULL)
{
return 0;
}

return(root->val + max(maxsum(root->left),maxsum(root->right));
}

- Shiva August 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

sounds good. but the tree could have more than 2 children.
anyways not any big change needs to be made to your code.

- john August 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is a very good solution, and as mentioned above, easily modifiable to fit a tree with N children per node. To elaborate, this is a Depth First traversal of the tree that moves to the farthest children and works backwards to the root. It should visit each node exactly once, and therefor its time complexity is O(n). Given that it is a recursive function that will add a sum variable to the stack with each call, it's space complexity becomes O(n) as well.

- masterjaso August 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

the tree is not sorted !

- samy September 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Are the traversals of the tree given to us on disk latency?

- hprem... October 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

This is a problem easily solved with dynamic programming and adapted to code, here's the subproblem formula

OPT(node x) = { x.val if x is a leaf ; else max(x.val + OPT(k)) where k cycles through all children of x

in code, and this might be a bit sloppy, and assuming all children of any node t are listed in an array of nodes called t.children, looks like:

int find_max(tree t){
if (t == NULL) return 0; //this should never be reached, but its good to be secure
int max = t.val;
for(int i = 0; i < t.children.length; i++){
int q = find_max(t.children[i]);
if(t.val + q > max) { max = t.val + q);
}
return max;
}

- Moony September 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Additionally, to speed this up from some ugly O(2^n) answer (and that's only assuming each has two children, ick, imagine the painful slowness) we can use what is called memoization, no not memorization, memoization.

As each max value for a node is found, we store it into a caching array, then upon the next time we want to get the value for that node, instead of having to run through the recursion all over again, we can simply look it up in O(1) time, this effectively gives us a runtime of

O(n log (n))

which is substantially better and far more scalable. This also eases strain on computation in the event that children have more than one parent, or other weird tree-witchcrafty things.

- Moony September 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

We can break the problem in two steps
1) Get the leaf node for which sum is maximum
2) Once we have target leaf node, print the path from root to traget

public boolean printPath(BinaryNode node, BinaryNode target)
	{
		if(node == null)
		{
			return false;
		}
		
		if(node.equals(target) || printPath(node.left, target) || printPath(node.right, target))
		{
			System.out.print(node.data + "-->");
			return true;
		}
		
		return false;		
	}
	
	private int maxSum = 0;
	private BinaryNode maxSumLeaf = null;
	
	private void getMaxSumVodeLeaf(BinaryNode node, int currentSum)
	{
		if(node == null)
		{
			return;
		}
		currentSum = currentSum + node.data;
		if(node.left == null && node.right == null)
		{
			if(currentSum >= maxSum)
			{
				maxSum = currentSum;
				maxSumLeaf = node;
			}
		}
		
		getMaxSumVodeLeaf(node.left, currentSum);
		getMaxSumVodeLeaf(node.right, currentSum);
	}
	
	public int getMaxSum(BinaryNode node)
	{
		if(node == null)
		{
			return 0;
		}
		maxSum = 0;
		maxSumLeaf = null;
		
		getMaxSumVodeLeaf(node, 0);
		
		return maxSum;		
	}
	
	public int printMaxSumPath(BinaryNode node)
	{
		getMaxSum(node);
		printPath(node, maxSumLeaf);
		System.out.println();
		return maxSum;
	}

- aviundefined September 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Please explain with a example. Thanks

- Aneek August 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

10
/ \
8 2
/ \ \
3 11 22
example this is the tree and when u add the elments of a path from root to leaf say (10+8+3=21) is smaller than (10+2+22=34) largest of alll the path so result is 34

- samy August 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

10
/ \
8 2
/ \ \
3 11 22

- samy August 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Another possible solution is
1) First find the maximum Sum
2) Then print the path which has sum = maximum sum found in first step

public void findSumPath(BinaryNode node, int currentSum, String path, int sum)
	{
		if (node != null)
		{
			currentSum = currentSum + node.data;
			path = path + node.data + "-->";

			if (currentSum == sum)
			{
				System.out.println(path);
				return;
			}
			else if (currentSum < sum)
			{
				findSumPath(node.left, currentSum, path, sum);
				findSumPath(node.right, currentSum, path, sum);
			}
			else
			{
				System.out.println("No such path exists");
				return;
			}

		}
	}

	public int findMaxSum(BinaryNode node)
	{
		if (node == null)
		{
			return 0;
		}

		return (node.data + max(findMaxSum(node.left), findMaxSum(node.right)));
	}

	public int printMaxSum(BinaryNode node)
	{
		int maxSum = findMaxSum(node);
		findSumPath(node, 0, "", maxSum);
		System.out.println();
		return maxSum;
	}
	
	private int max(int value1, int value2)
	{
		if (value1 >= value2)
		{
			return value1;
		}

		return value2;
	}

- aviundefined September 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

[This will give you the actual path, it's easier to just get the sum]
Do preorder traversal (yes, you can do preorder traversal on N-ary trees too), such that when you go to a node you increment a running sum by the value at that node, and when you exit the node you subtract that value back.

When you reach a child, add that child's value to sum, and store both (key of child, sum to child) into a hash or DirectAccessTable.

So this is O(n) as it visits each node once..

At the end linear scan the table for max, and get the key of the child.

- bigphatkdawg September 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The question says paths from root to leaf nodes so there is no need to store the sum for non-leaf nodes.

Regardless any solution needs to examine paths to all leaf nodes.

If we have parent pointers the storage becomes a little less:
Rather than storing all leaf node sums we just need to maintain pointer to the leaf node with max sum. Then at the end we can follow parent pointers from the max sum leaf node up to the root to print the path.

- Anonymous December 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

void maxSum( struct node *root, int *sum)
{
if( !root ) return;
int temp;
*sum = *sum + root->data;
temp = *sum;
maxSum( root->left , sum );
int lsum = *sum;
if( lsum < temp )
{
lsum = temp;
}
maxSum( root->right , &temp );
if( lsum < temp )
{
*sum = temp;
}
else
{
*sum = lsum;
}
}

- ashi January 03, 2014 | Flag Reply


Add a Comment
Name:

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

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More