Amazon Interview Question for Software Engineer / Developers






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

An idea: compare the last element of a list1(say a) with first element of other list2(say b). If a<b, just append the list2 to list1.
We can further optimise it by comparing fisrt with first as well to proceed with correct order of merging

- sachinvirgo February 26, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 vote

I don't think you can do it in O(n*log(K)). There are N sorted lists where each list has K elements. Just to traverse the list, you have to go through
(N * K) elements. (N*K) > (N * Log(K)). I think the best you can do is O (N*K log(K).
Here is the discussion.
https://www2.blogger.com/comment.g?blogID=6957414&postID=109840061746437225

- vodangkhoa January 18, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Assuming that size of each array is 'n' & there are 'k' such sorted arrays.
We are using a Min-Heap here.

Solution:
We assume that the lists are sorted in ascending order.
Insert all k elements at position 1 from each list into a heap. Use EXTRACT-MIN to obtain the smallest element (say x) of the heap.
Say then x came from list i, then take the next element from list i and insert it
into the heap. Continuing in this fashion yields the merged list. Clearly the running time is O(n log k)

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

It's an exercise problem straight from Cormen et al's 'Introduction to Algorithms' at the end of the chapter of Heapsort.
* In 3rd edition, it's Exercise 6.5-9
* In 2nd edition, it's Exercise 6.5-8

The problem asks an O(n log k)-time algorithm to merge k sorted lists into one sorted list where n is the total number of elements in all the input lists.

- f#ck April 16, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 3 vote

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Set;
 
 
public class MergeArrays {
 private static final int N = 7;
 private static HashMap<Integer, ArrayList<Integer>> arrayMap = new HashMap<Integer, ArrayList<Integer>>();
 private static int TOTAL = 0;
  
 public static void main(String[] args) {
  createArrays();
  System.out.println("Number of arrays: " + N);
  printArrays();
  ArrayList<Integer> mergedList = mergeArrays();
  System.out.println("Final merged lists data: ");
  printMergedList(mergedList);
  System.out.println();
   
 }
  
 public static void printMergedList(ArrayList<Integer> mergedList) {
  if (mergedList == null || mergedList.size() < 1) {
   System.out.println("Merged List is EMPTY!");
  }
  Iterator<Integer> iter = mergedList.iterator();
   
  while (iter.hasNext()) {
   System.out.print(iter.next() + " ");
  }
  System.out.println();
 }
  
 public static ArrayList<Integer> mergeArrays() {
  ArrayList<Integer> mergedList = new ArrayList<Integer>();
  Set<Integer> keySet = arrayMap.keySet();
  Comparator<Node> comparator = new NumericComparator();
  PriorityQueue<Node> minHeap = new PriorityQueue<Node>(TOTAL, comparator);
   
  Iterator<Integer> iter = keySet.iterator();
  while (iter.hasNext()) {
   int key = iter.next();
   ArrayList<Integer> list = arrayMap.get(key);
   if (list != null) {
    Integer data = list.remove(0);
    Node node = new Node(data, key);
    minHeap.add(node);
   }
  }
   
  while (minHeap.size() > 0) {
   Node node = minHeap.remove();
   //System.out.print(node.data + " ");
   mergedList.add(node.data);
   int id = node.id;
   ArrayList<Integer> list = arrayMap.get(id);
   if (list != null && list.size() > 0) {
    Integer data = list.remove(0);
    Node newNode = new Node(data, id);
    minHeap.add(newNode);
   }
  }
   
  return mergedList;
   
 }
  
 public static void createArrays() {
  Random rand = new Random();
  for (int i=0; i<N; i++) {
   int size = rand.nextInt(5) + 5;
   TOTAL += size;
   ArrayList<Integer> numList = new ArrayList();
   for (int j=0; j<size; j++) {
    int value = rand.nextInt(1000) + 1;
    numList.add(value);
   }
   Collections.sort(numList);
   arrayMap.put(i+1, numList);
  }
 }
  
 public static void printArrays() {
  Iterator it = arrayMap.entrySet().iterator();
   
  while (it.hasNext()) {
   Map.Entry<Integer, ArrayList<Integer>> pair = (Map.Entry<Integer, ArrayList<Integer>>)it.next();
   ArrayList<Integer> list = pair.getValue();
   Iterator liter = list.iterator();
   while (liter.hasNext()) {
    System.out.print(liter.next() + " ");
   }
   System.out.println();
  }
 }
}
 
class Node {
 int data;
 int id;
 Node(int data, int id) {
  this.data = data;
  this.id = id;
 }
}
 
class NumericComparator implements Comparator<Node> {
 
 @Override
 public int compare(Node o1, Node o2) {
  if (o1.data < o2.data) {
   return -1;
  } else if (o1.data > o2.data) {
   return 1;
  } 
  return 0;
 }
  
}

- vigneshselvakumar January 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

that was awesome. some explanation would have helped though!

- codewarrior February 25, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I failed the interview but later realized that this was the question straight from Cormen's book. Basically the solution involves usage of heap. I found the solution on the internet though can't remember the site address currently.

- ss December 06, 2006 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

More pointers would be appreciated

- Coder October 23, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Use merge sort

- Chiranjit December 07, 2006 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

well... ok, but you're not writing one thing: K >= N, otherwise you could sort N elements in O(N) time.

- Anonymous December 13, 2006 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

can anyone post a pseudocode, atleast!!!

- kg January 18, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

It is possible to do this in O(n*logK). If you use the medians, you can decide whether an element is to the left or right of the median.

- Jack January 19, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is a linked list. You don't have random access memory. To find the median, you need to traverse the linked list which is N.

To claim that you can sort a N sorted lists where each list has K elements in Nlog(K) is similar to claiming that you can sort two linked lists in N Log(2).

Linked list 1: 1 5 9
Linked List 2: 3 4 8

I do not think it can be done with the above linked lists.

- vodangkhoa January 21, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

(too many Jacks...)

It is very simple to see that O(n*k) is required. This is the size of the output list that will be generated, one character at a time.

- Jack November 14, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

L1:456 L2:123 ... LN

1.
1<5? Yes
1<4? Yes
L1: 1456
L2:23

2.
2 between 4&5? No
2 < 4? Yes
L1:12456
L2: 3

3.
3<4? Yes
3 b/w 1&2? No
3<1? No
3>2? Yes
L1:123456.
L2:

4. There are N-1 lists remaining. Do L2 with L3, and so on up to N.

- Jack January 19, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi
this way at last step
there will be two list
first of k elements and
second of k(n-1) elements

so it will take k* log k(n-1) time

- Anonymous March 30, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think the correct question and answer to this question is given in the link below
http://home.tiac.net/~cri/2004/ksort.html

- Krrish March 04, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Also, the question must be k sorted lists each of size n and not the converse if you want to do it in O(n lg k) time.

- Krrish March 27, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Krrish.
I checked the method the link you posted earlier
But I couldnt see how that one sort these lists.

- Noname June 30, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

To merge k sort array in one sorted array.
Suppose we have k sorted arrays. We have to merge this k sorted arays.

int a[]={1,4,7};
int b[]={2,5,6};
int c[]={0,3,8};
int d[]={9,10,11};

First we will store this k sorted arrays into one big array temp.
int temp[];
Second; we will again sort this temp array just like we sort the individual array in k sorted array.

Hope this solution will work.

- Anonymous July 04, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

there would be NK elements in the big temp array and sorting of which is
O(NK logNK)

- Ramu October 08, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nklog(N) not Nklog(NK) in this case
as lists will be atleast of k size

- words&lyrics July 26, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I guess it should be O(n*k*log(n))

at the first iteration, we combine every two lists into one, thus we need O(n*k) to reduce n lists to n/2 lists,

at the second iteration, we again need O(n*k) to reduce n/2 lists to n/4 lists.

There are total log(n) such interation, so we have O(n*k*log(n))

- jerryunsw September 04, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

We need to use binomial heaps to merge.

- Don September 09, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Don, can you explain little more and post a URL

- Ramu October 08, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Merge every two sorted lists into one list. Each merge takes O(k).
repeat above operation.

It will take logn/log2 times to get a sigle sorted list. Therefore we get O(k*log(n))

- Tonyqian November 18, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

step 1: use Binary Search tree to find the appropriate place o(log k)
step 2 : use it for each and every element in other sorted list. o(nlog k)

- CodeGuru December 03, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Sorting 2 lists is O(logn). Since there are n lists, O(nlogn).

- Jack December 12, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Like merge sort, merge the list in pairs recursively.

For n lists of average size k, it is O(klgn).

- Anonymous February 28, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

First Approach -
Create Interval Tree
- Traverse logn and merge from bottom to top in order k.
Total O(KLogN)

Second Approach
Merge two list - O(K)
Foreach n pairwise (Merge sort) - Logn
n/2 pairs..n/4 pairs...n/8 pairs

Total - O(KLogN)

- YetAnotherCoder October 23, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Jerry solution is correct..
u should to merge like a tournament tree with n players(lists)
and winner will be the resultant merged list

- deaGle October 31, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Guys, do not waste your time figuring out how you can do O(nlogk). It is just impossible unless you use some linear-time sorting methods...let's make k=1...You will see why

- Z January 02, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

(Y)

- Anonymous April 03, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Try this - KWayMerge -
code.google.com/p/kway/

- Ajeet August 27, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You can merge starting from 2 lists and then continue. Since there are k lists logk merges are required each merge taking O(n) time. So run time complexity of algorithm is (Onlogk)

public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if(lists.size() == 0) return null;
    		Queue<ListNode> q = new LinkedList<ListNode>();
			for(ListNode n : lists){
				q.add(n);
			}
			while(q.size() != 1){
				ListNode l1 = q.remove();
				ListNode l2 = q.remove();
				q.add(merge(l1, l2));
			}
			return q.remove();
    }
    
    public ListNode merge(ListNode l1, ListNode l2) {
    	if (l1 == null)
			return l2;
		if (l2 == null)
			return l1;
		ListNode head = null;
		if (l1.val < l2.val) {
			head = l1;
			l1 = l1.next;
		} else {
			head = l2;
			l2 = l2.next;
		}
		head.next = merge(l1, l2);
		return head;
	}

}

- Aayush Bahuguna February 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

We can put each element in a tree say BST and then print the tree in inorder or store the elements into an another array inorder.

- vigneshb06 June 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.ArrayList;
import java.util.List;

public class MergeLists {

	public static class Node implements Comparable<Node> {

		int data;
		Node next;

		Node(int data){
			this.data = data;
		}
		@Override
		public int compareTo(Node o) {
			if (this.data == o.data) {
				return 0;
			} else if (this.data < o.data) {
				return -1;
			}
			return 1;
		}
	}

	private Node resultList;
	private MinHeap<Node> minHeap;

	
	public MergeLists(List<Node> lists) {
		
		this.minHeap = new MinHeap<Node>(lists.size(), lists);
		this.minHeap.buildHeap();
	}

	public void merge() {

		Node tail = null;
		while (!minHeap.isEmpty()) {

			Node node = minHeap.deleteMin();
			
			if (resultList == null) {
				resultList = node;
				tail = node;
			} else {
				tail.next = node;
				tail = node;
			}
			if (node.next != null) {
				minHeap.insert(node.next);
			}
			node.next = null;
		}
	}

	public static void main(String[] args) {
		
		List<Node> list = new ArrayList<MergeLists.Node>();
		Node n1 = new Node(1);
		n1.next = new Node(2);
		n1.next.next = new Node(3);
		n1.next.next.next = new Node(5);
		n1.next.next.next.next = new Node(7);
		list.add(n1);
		
		Node n2 = new Node(4);
		n2.next = new Node(6);
		n2.next.next = new Node(8);
		n2.next.next.next = new Node(10);
		list.add(n2);

		Node n3 = new Node(9);
		n3.next = new Node(11);
		n3.next.next = new Node(12);
		n3.next.next.next = new Node(13);
		list.add(n3);

		Node n4 = new Node(-4);
		n4.next = new Node(-2);
		n4.next.next = new Node(-1);
		n4.next.next.next = new Node(14);
		list.add(n4);

		Node n5 = new Node(-3);
		list.add(n5);
		
		MergeLists ml = new MergeLists(list);
		ml.merge();
		ml.printList();
	}

	private void printList() {
		
		Node temp = resultList;
		while(temp != null) {
			System.out.print(temp.data + ", ");
			temp = temp.next;
		}		
	}
}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MinHeap<E extends Comparable<E>> {

	private List<E> elements;
	private int k;

	public MinHeap(int k, List<E> elements) {
		this.k = k;
		this.elements = elements;
	}

	public boolean isEmpty() {
		return k <= 0;
	}

	public void buildHeap() {
		for (int i = k / 2 - 1; i >= 0; i--) {
			heapify(i);
		}
	}

	public void heapify(int root) {

		int left = leftChild(root);
		int right = rightChild(root);
		int min = root;
		if (k > left && elements.get(root).compareTo(elements.get(left)) > 0) {
			min = left;
		}

		if (k > right && elements.get(min).compareTo(elements.get(right)) > 0) {
			min = right;
		}

		if (min != root) {
			swap(min, root);
			heapify(min);
		}

	}

	public void insert(E e) {
		elements.add(k++, e);
		int parent = parent(k - 1);
		int i = k - 1;
		while (parent >= 0
				&& elements.get(parent).compareTo(elements.get(i)) > 0) {
			swap(parent, i);
			i = parent;
			parent = parent(i);
		}
	}

	public E deleteMin() {
		swap(0, k - 1);
		k--;
		heapify(0);
		E e = elements.get(k);
		elements.remove(k);
		return e;
	}

	private void swap(int i, int j) {
		E temp = elements.get(i);
		elements.set(i, elements.get(j));
		elements.set(j, temp);
	}

	private int parent(int i) {
		return (i - 1) / 2;
	}

	private int leftChild(int i) {
		return 2 * i + 1;
	}

	private int rightChild(int i) {
		return 2 * i + 2;
	}

	public static void main(String[] args) {
		Integer[] elements = { 3, 2, 1, 5, 4, 0, 1, -1, -9 };

		ArrayList<Integer> elementList = new ArrayList<Integer>(
				Arrays.asList(elements));
		int k = elements.length;
		MinHeap<Integer> heap = new MinHeap<Integer>(k, elementList);
		heap.buildHeap();
		for (int e : elementList) {
			System.out.print(e + ", ");
		}

		System.out.println();
		System.out.println(heap.deleteMin());
		for (int e : elementList) {
			System.out.print(e + ", ");
		}
	}
}

- newLearner July 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Solution:
We assume that the lists are sorted in ascending order.
Insert all k elements at position 1 from each list into a heap. Use EXTRACT-MIN to obtain the smallest element (say x) of the heap.
Say then x came from list i, then take the next element from list i and insert it
into the heap. Continuing in this fashion yields the merged list. Clearly the running time is O(n log k)

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

Assuming that size of each array is 'n' & there are 'k' such sorted arrays.
We are using a Min-Heap here.

- RAKESH October 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Various approaches: writeulearn.com/leetcode-merge-sorted-lists/

- Taru January 12, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Take k sorted arrays of arbitrary sizes, returns a unified sorted Array

/**
 * Class  takes a n*k dimensional array and outputs a single sorted  array of size n*k
 */
public class KArySorting {

	public static void main(String[] args) {

		// in an array- Multi dimensional 
		int arr[][] = new int[][] {
				{1,2,3,4},
				{15,16,17,18},
				{3,3000},
				{0,3,1191,9898},
				{2, 6, 12, 34,50},
				{1, 9, 20, 1000,1200},
				{23, 34, 90,150,190},
		};
		
		//If all arrays are of same size as in merging k sorted Lists, this Step is not required
		int N=0;
		for (int row = 0; row < arr.length; row++)
		{
			N = N+arr[row].length;
		}
		KArySorting kSorting= new KArySorting();
		KArySorting.Struct structNode =  kSorting. new Struct(); 
		int[] result = structNode.kWayMerge(arr,N);
		System.out.println("Printing Final Array  "+result.length);
		for(int i=0;i<result.length;i++)
		{
			System.out.println(result[i]);
		}

	}

	class Struct
	{
		int data;
		int indexofArray;
		int indexOfNextElement;
		int size;

		private int heapSize()
		{
			return size;
		}	

		private int getLeftChild(int i)
		{
			return 2*i+1;
		}

		private int getRightChild(int i)
		{
			return 2*i+2;
		}

		public void swap( Struct[] arr, int index1, int index2) {
			Struct temp = arr[index1];
			arr[index1] = arr[index2];
			arr[index2] = temp;			
		}

		public  void minHeapify( Struct arr[], int index)
		{
			int lIndex = getLeftChild(index);
			int rIndex = getRightChild(index);
			int smallest;
			if(lIndex <= heapSize() && arr[lIndex].data<arr[index].data)
			{
				smallest = lIndex;
			}
			else
			{
				smallest = index;
			}
			if(rIndex <= heapSize() && arr[rIndex].data<arr[smallest].data)
			{
				smallest = rIndex;
			}
			if(smallest != index)
			{
				swap(arr, index,smallest);
				minHeapify(arr, smallest);
			}
		}

		public void buildMinHeap(Struct[] arr)
		{
			this.size = arr.length-1;
			for(int i = (int)Math.floor(arr.length/2) ; i >= 0 ; i--)
			{			
				minHeapify(arr, i);
			}

		}

		// Returning Just the Data, i.e integer value. 
		public int[] kWayMerge( int [][] arr, int n)
		{
			int k = arr.length;
			Struct[] dataArray = new Struct[k];
			for (int i = 0; i < k; i++)
			{
				dataArray[i] = new Struct();
				dataArray[i].data = arr[i][0]; // Store the first element
				dataArray[i].indexofArray = i;  // Stores the index of array from which the elem was picked to be stored in Heap
				dataArray[i].indexOfNextElement = 1;  // Index of next element to be stored from array, default to 1st element
			}
			buildMinHeap(dataArray);

			int [] output = new int[n];// if n is size of  single array, total = n*k

			for (int count = 0; count < output.length; count++)
			{
				// Create a pointer Node Root from the top of Min Heap
				Struct root = dataArray[0];
				// Put it in final Array
				output[count] = root.data;
				// Check if the k array still has elements
				if (root.indexOfNextElement < arr[root.indexofArray].length)
				{
					// get the new Root from the Array which has prevous root
					root.data = arr[root.indexofArray][root.indexOfNextElement];
					root.indexOfNextElement += 1;

				}
				// case when one of the array has reached its end				
				else
				{			
					//Put the last data in the min heap on the Top as the array is extinguished
					dataArray[0]= dataArray[size];					
					// Reduce HeapSize
					size--;// reduce heap size
					root=	dataArray[0];
				}
				dataArray[0] = root;
				minHeapify(dataArray, 0);
			}
			return output;
		}
	}
}

- Joshi June 07, 2015 | 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