Amazon Interview Question for SDE-2s


Country: India
Interview Type: Written Test




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

Here is what i can think of, let me know if you replied differently.
sort the data provided as input , and start inserting the data in binary tree from heightest input value so that all top values will be at low level and low values of input will be at high level. Insertion in tree should be done by traversing the tree in level order and left tree should be inserted before right tree. Total time to sort the input data O(nlogn)+building tree[O(n)]+calculating weight[O(n)]= Total TimeComplexity[O(nlogn)] ..

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

Consider these trees:
6
5
4
Sum = 6*1+5*2+4*3 = 28

And
5
4 6
Sum = 5*1 +4*2 + 6*2 = 25

So you solution don't work

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

Trying with formatting:

Consider these trees:
		6
	5
4
Sum = 6*1+5*2+4*3 = 28

And
		5
	4 		6
Sum = 5*1 +4*2 + 6*2 = 25

So you solution don't work

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

It seems only an almost completely balanced binary tree may give the least value.

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

@OTR, with your solution, how can you tell where to insert into a tree with both left and right trees non-null. Please clarify.

This is my thinking. Please go thru this solution and let me know if this is correct and optimized solution.

If at all building a tree is mandatory here,

- sort the array first (in descending order , eg: 7 6 5 4 3 2 1)
-build tree(max heap) with inserting 7 as root node and its position as 0 in the array.
- insert() function will calculater its next two elements as position * 2 + 1, and position * 2 + 2 as its left and right subtrees. Insert those array values accordingly.
-recursively call this on left sub tree and right subtree by sending their positions (2*x + 1, 2*x + 2), so that they will calculate their children using the same formula again.
-this ensures a height balanced heap
- level order traversal to calculate the total weight.

Requesting your replies....

- Anonymous January 09, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Anonymous, I don't understand why you go through steps 2-5, because you have a minimum weight tree after step 1. Why create a 2nd tree? In any case, this is a O(n*log(n)) solution, but there is a O(n) solution. See my solution below.

- gudujarlson January 09, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

why are we even constructing the final tree. the question is to only calculate the minimum tree weight..
just sort the array and dot multiply with
a[]={1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,.....}-> n length

example 4,5,6
sorted 6,5,4
answer= 6*1+5*2+4*2 = 24

- kkr.ashish August 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

Why don't build binary tree (where top is max element) - in that case the further element from the root (greater level) - the smaller it's value - this should give minimum sum.

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

Sorry, instead binary tree, should be binary heap

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

If you start building binary heap from original array, there can be a situation described below by vgeek - when value in left branch of second level is lower than some value in the right branch of third level. This will cause not a minimal weight of a tree.

- golodnov.kirill August 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

As this is binary tree, so we have to sort array in descending order and treat this array like we have stored max-heap. So this will be complete binary tree which is left aligned.
Then calculate tree weight.

It is simple

- Nitin Gupta August 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

why not just create a max heap out of the array of element. Creating a max heap can be done in o(n) if it is balanced!

- Nirav August 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

But creating a max heap can cause problems as:
Suppose input is: 1 2 4 5 6 7 8
Max Heap:
8
4 7
1 2 5 6
But if we first sort the array in descending order and then make a complete binary tree as:
8
7 6
5 4 2 1.
Definitely the cost of the second method is less.

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

This is the solution that I came up with too. To minimize the tree weight, we have to minimize the two its contributing factors - the level and the product of a number and its level. To achieve this, we need a binary heap (yielding the minimum tree height), while the numbers have to be entered into the heap from highest to lowest. This approach leads us the the max binary heap.

- ashot madatyan August 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

But don't you think managing heap will take O(nlogn)?

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

The condition of a heap is that every parent value is bigger than the children value, but not that every value in one level is bigger then the values in the below level.

The heap data structure can be used, but not the algorithms.

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

@gonzo: The binary heap has two properties: heap and shape. Here, we are using its shape property, i.e. inserting items (nodes) from left to right. This yields us the shape of the binary heap when we insert the original values from highest to lowest into the binheap.
Excerpt from wiki:

Shape property
The tree is a complete binary tree; that is, all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right.

BTW, another advantage of the binary heap is that it is an in-place algorithm abd does not require any additional storage as a scratch space.

- ashot madatyan August 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Let's consider the input is sorted in descending order.
10,9,8,7,6,5,4,3,2,1
Obviously for problem definition of the binary tree weight to have the minimal weight the "heavy" elements must be placed close to the root.
This means, that in our case root node holds 10, it's children hold 9 and 8, their children hold 7,6 and 5,4 respectively. And so on.
So we have the heap. If you want to present it not as an array, but as a tree you have to “translate” indexes to left/right pointers.

//one based calculations
getLeft(vector<int> input, int parent) {
if (parent*2 <= input.length())
return parent*2;
return -1;
}

Simular getRight(…)

Even better one can write a function getParent()

If the input is not sorted, sort it first.

In other words the time complexity of building the tree is 0 if the input is sorted and O(n*log(n)) if not.

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

O(n) Solution

The straight forward way to solve this problem is to sort the array and then calculate the tree weight. This has a complexity of O(n*log(n)). However we don't need to fully sort the array to produce a minimum weight tree. There are many other orderings that work because the order within each level does not matter. So there should be a way to solve the problem faster than fully sorting the array and perhaps even a way with less complexity than O(n*log(n)). And guess what, there is.

The basic idea is to find the 1st, 3rd, 7th, 15th, ... (n/2-1)th largest values in the array and then partition the array about those values. To do that we partition the array around its (n/2-1)th largest value, then recursively partition the left side about its (n/2-1)th largest value until no more partitions are possible. We use the selection algo to do each partition, but in this case, we don't care about the normal output of the selection algo: the kth largest element. Rather we care about the side effect of what it does to the input array, i.e. partitioning the array about its (n/2-1)th largest value. The end effect of this partitioning is a binary tree with minimum weight.

The selection algo has an average complexity of O(n) and it will be run log(n) times, but each time it is run n shrinks by a factor of 2 (n + n/2 + n/4 + n/8 ... = 2n), thus the overall complexity is O(n). CAVEAT: the worst case performance remains O(n^2) and depends on the choice of pivots.

int findMinimumWeight(int a[]) {
		optimize(a);
		return calculateWeight(a);
	}
	
	int calculateWeight(int a[]) {
		int weight = 0;
		int level = 0;
		int nextLevel = 1;
		for (int i = 0; i < a.length; i++) {
			if (i == nextLevel) {
				++level;
				nextLevel = (1 << level) - 1;
			}
			weight += a[i]*(level+1);
		}
		return weight;		
	}
	
	int[] optimize(int a[]) {
		iterations = 0;
		for (int k = a.length; k > 1; k /= 2) {
			selectLargest(a, 0, k-1, k / 2 + 1);
		}		
		System.out.println("n= " + a.length + " iterations=" + iterations + " efficiency=" + ((float)iterations / a.length) + " log(n)=" + Math.log(a.length));
		return a;
	}
	
	// Selects the kth largest value from the array.
	// As a side effect, it partitions the array around the kth largest value.
	// O(n)
	int selectLargest(int a[], int i, int j, int k) {
		//System.out.println(i + "," + j + "," + k);
		++iterations;
		if (i == j) {
			return k == 1 ? a[i] : -1;
		}
		int pivot = a[i + (j - i) / 2];
		int pivotIndex = partition(a, i, j, pivot);
		int kprime = pivotIndex - i + 1;
		if (kprime == k) {
			return pivot;
		}
		if (kprime < k) {
			return selectLargest(a, pivotIndex + 1, j, k - kprime);
		}
		else {
			return selectLargest(a, i, pivotIndex - 1, k);
		}
	}
	
	int partition(int a[], int i, int j, int pivot) {
		int k = i;
		while (k <= j) {
			++iterations;
			if (a[k] == pivot) {
				++k;
			}
			else if (a[k] > pivot) {
				swap(a, i, k);
				++i;
				++k;
			}
			else {
				swap(a, k, j);
				--j;
			}
		}
		return k - 1;
	}
	
	void swap(int a[], int i, int j) {
		int tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}

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

if we sort the array and make a balance binary tree then it give the minimum weight binary tree

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

// LearnApplication.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Stack.cpp"
#include <hash_map>
#include <string>
#include <iostream>
#include <hash_map>
#include <stdio.h>
#include <sstream>

void merge(int*,int*,int,int,int);
void mergeSort(int* a, int* b, int low, int high){
int pivot;
if (low<high){
pivot=(low+high)/2;
mergeSort(a,b,low,pivot);
mergeSort(a,b,pivot+1,high);
merge(a,b,low,pivot,high);
}
}
void merge(int* a, int* b, int low, int pivot, int high){
int h,i,j,k;
h=i=low;
j=pivot+1;
while(h<=pivot && j<=high){
if (a[h]>=a[j]){
b[i]=a[h];
h++;
}else{
b[i]=a[j];
j++;
}
i++;
}
if(h>pivot)
{
for(k=j; k<=high; k++)
{
b[i]=a[k];
i++;
}
}
else
{
for(k=h; k<=pivot; k++)
{
b[i]=a[k];
i++;
}
}
for(k=low; k<=high; k++) a[k]=b[k];

}
typedef struct node
{
struct node*left;
struct node*right;
char data;
}node;

node* createFromArray(int c[],int n){
node* tree=NULL;
if (c[n]!='\0'){
tree=(node*)malloc(sizeof(node));
tree->left=createFromArray(c,2*n+1);
tree->data=c[n];
tree->right=createFromArray(c,2*n+2);
}
return tree;
}
void parseInOrder(node* tree){
while(tree!=NULL){
parseInOrder(tree->left);
printf("%d \t",tree->data);
parseInOrder(tree->right);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int c_array[]={12,31,5,12,65,23,21,43};
int num;
num = sizeof(c_array)/sizeof(int);
int b[8]={0};
mergeSort(c_array,b,0,num-1);
node *tree;
tree=createFromArray(c_array,0);
parseInOrder(tree);
}

- Priyank Jain February 08, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void subTreeLevelSum(List<Integer> item) {
		if (root == null) {
			return;
		}
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		sumSubTreeWithLevel(root, item, 1, map);
		Set<Integer> set = map.keySet();
		int min = Integer.MAX_VALUE;
		int givenkey = Integer.MAX_VALUE;
		for (Integer key : set) {
			int sum = map.get(key);
			if (sum < min) {
				givenkey = key;
				min = sum;
			}
		}
		System.out.println("Minimum Sum : " + min + " with a given key : " + givenkey);
	}
	
	private void sumSubTreeWithLevel(TreeNode node, List<Integer> items, int level, Map<Integer, Integer> map) {
		if (node == null) {
			return;
		}
		if (items.contains(node.data)) {
			int sum = sumUpTheBinaryTree(level, node);
			map.put(node.data, sum);
		}
		sumSubTreeWithLevel(node.left, items, level + 1, map);
		sumSubTreeWithLevel(node.right, items, level + 1, map);
	}
	
	private int sumUpTheBinaryTree(int level, TreeNode node) {
		if (node == null) {
			return 0; 
		}
		int sum1 = sumUpTheBinaryTree(level + 1, node.left);
		int sum2 = sumUpTheBinaryTree(level + 1, node.right);
		int result = node.data * level + sum1  + sum2;
		return (result);
	}

INPUT: 
		TreePath t = new TreePath();
		t.insert(4);
		t.insert(2);
		t.insert(3);
		t.insert(1);
		t.insert(6);
		t.insert(5);
		t.insert(7);
//		t.postorder();
		List<Integer> items = new ArrayList<Integer>();
		items.add(6);
		items.add(2);
t.subTreeLevelSum(items);

OUTPUT:
-------------
Minimum Sum : 16 with a given key : 2

- anand June 01, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

awesome answer.

- Anonymous August 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

This is a wrong solution. If you put the top most value in the low level then all the other values would be in the left of it which would increase the depth of the tree.
I think the right solution is first sort the tree and then put the median on the root and recursively process the left and the right of the tree

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

This is simple binary tree, not Binary Search Tree, in case of BST your point will be valid. Correct me if i am wrong.

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

The question does not say it is a binary search tree. So in a binary tree we don't need to think about the order of numbers.

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

does your approach works for below data?

1 2 100 here median is 2

- algos August 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

In the question it was mentioned as a Binary Tree not BST.
Another problem i found was, there can be multiple binary trees possible from the given set of data (tree with one or two node is also a valid binary tree).
my approach obviously didn't work, as i couldn't clear the interview :(

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

Complete wrong.

- Hello world August 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

First, Sort the given data.O(nlogn) time.
Second, take the middle value of the sorted data and Make middle value as root node of binary tree.If total number of data is even, then take middle value from (middle +1) position.Now Insert values in binary tree from middle value to least less value (middle to left side) and later insert values in binary tree from highest value to the middle value (right to middle side).

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

There is no need to insert the sorted array into a binary tree as the sorted array is already the correct binary tree representation.

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

Can you tell is this tree a BST?

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

it was written as binary tree.. but i don't mind getting a solution considering BST

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

@prabal77

What was your answer?

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

My answer was wrong.. coz i was kicked out of the interview. :)
After the interview, a thought came to my mind that the catch was to find the minimum weight out of all the binary trees possible from the given set of data. There can be multiple binary tree possible from a given set of data e.g. a tree with only two or single node is also a valid tree. We can sort the data and return the value of the smallest data from the list.. As that can be weight of a binary tree with only one node..

Not sure if i am correct or not.. but just a thought.

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

Can anybody post the pseudo code of the implementation of the above problem

- Anonymous August 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

I am stuck with another problem. can anybody help me? the link to the problem is commissies.ch.tudelft.nl/chipcie/archief/1999/ekp/html/proba.html

- Anonymous August 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

What about to sort elements in decreasing order and make BFS to fill level by level so i grantee smallest level to the greatest value ?

- spik August 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

this is a simple greedy algorithm question.
just look for optimal binary search trees..
First sort all the numbers.
Consider each number is a tree node.
Take the two lowest numbers and make them as siblings. mark the parent with the sum of their values. and remove those from the set of numbers and put the new parent.
keep on doing this until only one node is left . which is the root of tree

- Paresh September 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

why are we building BST when only binary tree is asked in question , sort the elements (nlogn) and then do a level order insertion from max to min will result in a minimum weight binary tree (not BST)

- Anonymous September 07, 2013 | 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