Amazon Interview Question for Software Engineer Interns


Country: United States
Interview Type: Phone Interview




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

Here is my idea.

(A) Let's take the smallest element from each array. For each element we will remember from which array did we take it. Sort them and add to the queue this way : the smallest element will be on the first place.

(B) After this, we know the first and the last element. Let's count length of the interval.
Next step is to pop element (let's call it x) and push next to x element, from the same array. Calculate length of the interval and repeat (B) until one of the arrays reaches its upper bound.

- GK February 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Update: Found a bug in my idea. We need to use priority queue , because newly added element may be smaller than actual max element. So, because of it, there is no need to sort first elements , just add them (the value will play the role of priority) in queue. If we want to calculate actual length, just need to ask queue for first and last element.

- GK February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

A minHeap would only return the min value. How could you have a minHeap return a max value?

- Guy February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I guess it is correct (after using the PQ). We have to monitor first and last to find the smallest interval.

- Ehsan February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

What about a binary search tree? You can get min and max both in logarithmic time.
Maybe Queue is a misnomer since you don't respect the FIFO order.

- Ehsan February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

excellent idea, I LOVE that.

- samuel February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you elobrate it with an example. I am sorry, I could not get your algorithm

- Chaitanya February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Chaitanya, here is an example:

input {0,10,255} {2 , 11 , 257} {4,12,258}

Let's take the first element from each array and push them into priority queue.

step 0: queue: [0,2,4] range:0-4
step 1: pop 0 from queue , push next element to 0 from first array
queue: [2,4,10] range: 2-10
step2: pop 2 , push 11
queue: [4,10,11] range: 4-11
step3: pop 4 , push 12
queue: [10,11,12] range: 10-12 <----- minimal range

etc...

- GK February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 votes

You algorithm doesnt work for the following example.

input: {2, 20, 10} (1, 5, 6} (22, 23, 24}
Lets take the first element from each array and pust them into priority queue. I understand that I should not sort the elements alter every step as you mentioned above. Correct my understanding if it is wrong

step0: queue: [2, 1, 22] range:2-22
step1: pop 2 from queue, push next element to 2 from first array.
queue: [1, 22, 10] range: 1-10 [This is an invalid range and no element in array 3 is within this range]
step2; pop 1, push 5
queue: [22, 10, 5] range: 22-5
step3: pop 22, push 23
queue: [10, 5, 23] range: 10 - 23 [This is an invalid range and no element in array 2 is within this range]
step4: pop 10, push 20
queue: [5, 23, 20] range: 5-20 [This is an invalid range and no element from array 3 is within this range]
Termenation step reached.


Please corect my understanding if it went wrong somewhere.

- Chaitanya February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

1. you should be using a priority queue or a BST as per the discussion above. So [1, 22, 10] will have a range of 1 - 22 and not 1 - 10. BTW in step 0, you should have removed 1 from [2, 1, 22] and not 2.

2. I notice that you do not have a sorted array (could be a typo)!

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

@GK in the example you have given to chaitanya , you did not reach to upperbound of any of the array, but you still declare 10 -12 as a minimal range.
Can you please explain what do you mean by reaching upperbound ?

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

It works well with a balanced BST
with each node having value array and index
get min and max every time get range
delete min
insert next from same array

- GS June 07, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

The minimum possible range will be,

Min (Max value of each array) -- Max(Min value of each array).

Is this right ?

- Anonymous February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

[2,10]
[3,7]

Your answer is Range(3,7) which is wrong.

- mahdi.oraei February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class minArrayRa​nge
{
  public static void main(Strin​g args[])
  {

  int [][] arrArrays=​{{3,4,5}, { 5, 58, 62}, {212, 434, 3333}};
  int []range=ge​tMinRange(​arrArrays)​;
  System.out​.println("Min range = ​min = "+range[0] + " max = " + range[1]);
  }

 static int [] getMinRang​e(int [][] arrArrays)
 {

  int max=-99999​, min=99999;
  for ( int i=0; i < arrArrays.​length; i++)
  {
  if(max < arrArrays[​i][0])
  {
  max=arrArr​ays[i][0];
  }

  if(min > arrArrays[​i][0])
  {
  min=arrArr​ays[i][0];
  }
 }

 int a[]= { min, max};
 return a;

}

}

- Shubhangi February 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Greedy algorithm is not appropriate for this question.
counterexample : int [][] arrArrays = ​new []{new []{3,256}, new[]{ 6,257},new[] {9, 258}};

Your code will say that the interval is 3-9, when minimum interval is 256-258.

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

WRONG SOLUTION (misunderstood the question)
You need to find maximal value among all minimums, and minimal value among all maximums. If maximal minimum is less than minimal maximum, than you can use a range of size one, it may be any number within that range.

void Calculate(const std::vector<std::vector<int> >& src, int& l, int& r){
	int mn = src[0].front();
	int mx = src[0].back();
	for(int i = 1; i < src.size(); ++i){
		mn = std::max(mn, src[i].front());
		mx = std::min(mx, src[i].back());
	}
	if(mn <= mx) mx = mn;
	l = mn;
	r = mx;
}

UPD: Sorry, there was a copy-paste mistake. Fixed now.

UPD2: For {0,10,255} {2 , 11 , 257} {4,12,258} the answer will be any two equal numbers from the range [4, 255], because we need minimal range, in my implementation it's [4, 4].

- marut February 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

What will be the answer for {0,10,255} {2 , 11 , 257} {4,12,258} ?

- GK February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

marut , I suppose you haven't read question carefully. You need to find minimum range, which will contain at least one element from each array. For example {0,10,255} {2 , 11 , 257} {4,12,258} the correct answer is 10-12 , the range is minimum and there is element in each array, which contains in this interval 10 from 1-st array , 11 from second and 12 from third.

- GK February 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

GK, you are right, sorry, I misunderstood the question.

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

How about first merge all sorted array and then traverse the merged list while keeping a window, make sure elements inside the window can be found in every original lists and keep updating the smallest window size.

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

I used divide and conquer strategy and it works. Yet, there can be one improvement and that is optimizing the size of nums array.

import java.util.ArrayList;


public class Main {
	ArrayList<Integer[]> arrays;
	int[] nums;
	Range bestRange;
	
	public Main(ArrayList<Integer[]> arrays) {
		this.arrays = arrays;
	}

	private void solve() {
		int min = findMin(arrays);
		int max = findMax(arrays);
		nums = new int[max-min+1];
		for (int i = min; i <= max; i++) {
			nums[i-min] = i;
		}
		
		bestRange = setBestRange(0,nums.length-1);
		System.out.println(bestRange.min + "\t" + bestRange.max);
	}
	
	//divide and conquer
	private Range setBestRange( int first, int last) {
		
		if(first == last){
			Range r = new Range(nums[first],nums[first]);
			if(doesAllArraysHave(r)){
				return r;
			}else
				return null;
		}
		
		if(first == last -1){
			Range r = new Range(nums[first],nums[last]);
			if(doesAllArraysHave(r)){
				return r;
			}else
				return null;
		}
		
		if(doesAllArraysHave(new Range(nums[first],nums[last])) == false){
			return null;
		}
		
		int mid = (last - first) / 2 + first;
		Range firstRange = setBestRange(first, mid);
		Range secondRange = setBestRange(mid+1, last);
		int p = mid;
		int q = mid+1;
		
		Range combination = new Range(first,last);
		for (int i = mid; i >= first ; i--) {
			for (int j = mid+1; j <= last; j++) {
				Range temp = new Range(nums[i],nums[j]);
				if(doesAllArraysHave(temp) && temp.getRange() < combination.getRange()){
					combination = temp;
				}
			}
		}
		
		return minRangeofThree(firstRange, secondRange, combination);
		
	}
	
	// In the divide and conquer strategy, which division is better?
	public Range minRangeofThree(Range r1, Range r2, Range r3){
		if(r1 == null && r2==null && r3==null) return null;
		int r1GetRange = (r1 == null ? Integer.MAX_VALUE : r1.getRange());
		int r2GetRange = (r2 == null ? Integer.MAX_VALUE : r2.getRange());
		int r3GetRange = (r3 == null ? Integer.MAX_VALUE : r3.getRange());
		
		int min;
		if(r1GetRange < r2GetRange){
			min = r1GetRange;
		}else{
			min = r2GetRange;
		}
		
		if(r3GetRange < min){
			min = r3GetRange;
		}
		
		if(min == r1GetRange) return r1;
		if(min == r2GetRange) return r2;
		if(min == r3GetRange) return r3;
		return null;
	}

	private boolean doesAnArrayHave(Integer[] ints, Range r){
		for (int i = 0; i < ints.length; i++) {
			if( ints[i] >= r.min && ints[i] <= r.max)
				return true;
		}
		return false;
	}
	
	private boolean doesAllArraysHave(Range r){
		for (int i = 0; i < arrays.size(); i++) {
			if(!doesAnArrayHave(arrays.get(i), r))
				return false;
		}
		return true;
	}
	

	private int findMin(ArrayList<Integer[]> arrays) {
		int min = arrays.get(0)[0];
		for (int i = 0; i < arrays.size(); i++) {
			if(arrays.get(i)[0] < min)
				min = arrays.get(i)[0];
		}
		return min;
	}

	private int findMax(ArrayList<Integer[]> arrays) {
		int max = arrays.get(0)[arrays.get(0).length-1];
		for (int i = 0; i < arrays.size(); i++) {
			if(arrays.get(i)[arrays.get(i).length-1] > max)
				max = arrays.get(i)[arrays.get(i).length-1];
		}
		return max; 
	}
	

	public static void main(String[] args) {
		ArrayList<Integer[]> arrays = new ArrayList<Integer[]>();
		Integer arr1[] = new Integer[]{ 20,30,40,50};
		Integer arr2[] = new Integer[]{12,49,100};
		Integer arr3[] = new Integer[]{5,15,100};
		
		arrays.add(arr1);
		arrays.add(arr2);
		arrays.add(arr3);
		
		Main m = new Main(arrays);
		m.solve();
	}
}

- mahdi.oraei February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class FindRangeEachArrayContainingAtleats1Integer {

	public static void main(String[] args) {

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

		Set<Integer> se = new HashSet<>();

		for (int i = 0; i < a.length; i++) {
			se.add(a[i]);
		}
		for (int i = 0; i < b.length; i++) {
			se.add(b[i]);
		}
		for (int i = 0; i < c.length; i++) {
			se.add(c[i]);
		}
		int length = se.size();
		int i = 0,min=0,max=0;
		for (int a1 : se) {
			if (i == 0) {
				
				min=a1;
			}
			i++;

			if (i == length) {
				max=a1;
			}
		}

		 System.out.println("Range is={ "+min+ ",.....,"+ max + " } ");
	}

}

- Ravi Kumar February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Output-

Range is={ 1,....., 11 }

- Ravi Kumar February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This does not return the "minimum" range, which, in this case, should be 2-3

- edcent February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

import sys
from heapq import *

a1 = [1,6,8,10]
a2 = [3,9,20]
a3 = [6,10,20]

iters = [iter(a) for a in (a1, a2, a3)]

heap = [(it.next(), it) for it in iters]
heapify(heap)

min_range = (sys.maxint, (0,0))
max_element = None

while heap:
    v, it = heappop(heap)

    if max_element and v-max_element > 0:
        min_range = min(min_range, (v-max_element, (max_element, v)), key=lambda x:x[0])

    max_element = max(v, max_element)

    try:
        heappush(heap, (it.next(), it))
    except:
        break

print min_range[1]

- Anonymous February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the solution is wrong, please ignore

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

import sys
from heapq import *

a1 = [1,6,8,10]
a2 = [3,9,20]
a3 = [6,10,20]

iters = [iter(a) for a in (a1, a2, a3)]

heap = [(it.next(), it) for it in iters]
heapify(heap)

min_range = (sys.maxint, (0,0))

while heap:
    # should be fairly easy to add logic to track max element in heap
    _max = max(heap, key=lambda x:x[0])[0]
    _min, it = heappop(heap)

    min_range = min(min_range, (_max-_min, (_min, _max)), key=lambda x:x[0])

    try:
        heappush(heap, (it.next(), it))
    except:
        break

print min_range[1]

- Anonymous February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Please correct me if I am wrong but there is a simple greedy algorithm for this. Sort all the numbers from all the arrays. Start scanning numbers from the smallest (startNum)and stop at a number (stopNum) as soon as a number from each array has been scanned at least once (we know the array from which a number is taken from). save (stopNum,startNum). Next select, the next smallest number as the startNum for a new scan. Repeat till the end of the sorted array. Find the min range amongs the saved (stopNum,startNum) and that would be the answer.

- Anon February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

How do you guarantee that a number between (stopNum_i,startNum_i) and a number between (stopNum_i +1, startNum_i +1) is not the range we are looking for?

- mahdi.oraei February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

this is how the above greedy algo works on these arrays ->
a1 = {1 10 255} a2={2 11 255 256} a3= {4 10 257} the min range={10,11}
sorted array A={1 2 4 10 10 11 255 255 256 257}
ie is {a1[0] a2[0] a3[0] a1[1] a3[1] a2[1] a1[2] a2[2] a2[3] a3[2]}

from i=0 to A.length-1{
startNum = a[i]
Initialise an ArraysCoveredMap by adding only the array from which startNum was taken from;
from j=i+1 to A.lenght-1{
check the array A[j] belongs to and add it to the ArraysCoveredMap
if(all arrays were covered in the ArraysCoveredMap){
stopNum = a[j];
store {startNum, stopNum} somewhere
break;
}
}
}

check the min range amongst all the {startNum, stopNum} collected and that should be the answer

- Anonymous February 27, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Implementation of GK idea as Java Code.

import java.util.Comparator;
import java.util.PriorityQueue;

class Elem{
	int val;
	int pos;
	int arr;
	public Elem(int val, int pos, int arr) {
		super();
		this.val = val;
		this.pos = pos;
		this.arr = arr;
	}
}

public  class Problem88 {
	
	static class ElemComparator implements Comparator<Elem>{
		public int compare(Elem e1, Elem e2){
			return e1.val - e2.val;
	}

	public static void main(String args[]){
		int arr[][] =  {{0,10,255}, {2 , 11 , 257} ,{4,12,258}};
		ElemComparator ec = new ElemComparator();
		PriorityQueue pq = new PriorityQueue(10,ec);
		
		for(int i=0;i<arr.length;i++){
			Elem e = new Elem(arr[i][0],0,i);
			pq.add(e);
		}
		Elem mn;
		int min = -1;
		int max = 9999999;
		Elem mx;
		while(pq.size() == 3){
			mn = (Elem)pq.poll();
			mx = (Elem)(pq.toArray())[pq.size()-1];
			if((mx.val - mn.val) < (max - min)){
				min = mn.val;
				max = mx.val;
			}
			int arr1 = mn.arr;
			int pos = mn.pos;
			//if(pos >= arr[arr1].length-1 || mx.pos >= arr[arr1].length-1)
			//	break;
			if(pos < arr[arr1].length-1)
				pq.add(new Elem(arr[arr1][pos+1],pos+1,arr1));
		}
		System.out.println("Range is :: "+ min + " - " + max);
		}
	}
}

- Coder February 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I tested this for several of the inputs suggested above. Seems to work. Let me know if it breaks for any input. Use C++11 to compile it.

/*
 * min_range.cpp
 *
 *  Created on: Feb 26, 2014
 *      Author: nvankaya
 */

#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <set>

using namespace std;

bool check(deque<int>::const_iterator first,deque<int>::const_iterator last,int K){
  set<int> checker;
  set<int>::iterator c_itr;

  for(deque<int>::const_iterator d_itr = first;d_itr!=last;++d_itr){
      checker.insert(checker.begin(),*d_itr);
  }
  return (checker.size()==K);
}

void main(){
  vector<vector<int>> x = {{0,10,255}, {2 , 11 , 257}, {4,12,258} };//{{2, 20, 10}, {1, 5, 6}, {22, 23, 24}};//{{3,256},{ 6,257},{9, 258}};//{{19,33,256},{257,258,259},{2,5,255}};
  vector<vector<int>>::iterator x_itr;
  int K = x.size(); //Number of arrays

  vector<pair<vector<int>::const_iterator,vector<int>::const_iterator> > index;
  for(x_itr=x.begin();x_itr!=x.end();++x_itr){
      index.push_back(make_pair( (*x_itr).begin(),(*x_itr).end()));
  }
  std::cout<<"Original Arrays:\n";
  vector<pair<vector<int>::const_iterator,vector<int>::const_iterator> >::iterator i_itr;
  for(i_itr=index.begin();i_itr!=index.end();++i_itr){
      for(vector<int>::const_iterator tmp_itr=i_itr->first;tmp_itr!=i_itr->second;++tmp_itr){
          std::cout<<*tmp_itr<<",";
      }
      cout<<"\n";
  }

  vector<int> w;
  vector<int> s;
  while(1){
      int minval = 10000;
      int minval_num = -1;
      vector<int>::const_iterator *minval_index;
      int k=1;
      for(i_itr=index.begin();i_itr!=index.end();++i_itr,++k){
          if( (i_itr->first!=i_itr->second) & (minval>*(i_itr->first))){
              minval = *(i_itr->first);
              minval_index = &(i_itr->first);
              minval_num=k;
          }
      }
      if(minval==10000)
        break;
      w.push_back(minval);
      ++(*minval_index);
      s.push_back(minval_num);
  }
  //Merge the arrays in - last step in merge sort

  std::cout<<"Merger of the Arrays:\n";
  vector<int>::const_iterator itr;
  for(itr=w.begin();itr!=w.end();++itr){
      std::cout<<*itr<<",";
  }
  std::cout<<"\nCorresponding label of original arrays:\n";
  for(itr=s.begin();itr!=s.end();++itr){
      std::cout<<*itr<<",";
  }

  deque<int> window;
  vector<int>::const_iterator s_itr = s.begin();
  vector<int>::const_iterator w_itr = w.begin();
  int lowerbound,upperbound,range=0,minrange=100000;
  for(s_itr=s.begin();s_itr!=s.end();++s_itr,++w_itr){
      window.push_back(*s_itr); //expand the window
      if(check(window.begin(),window.end(),K)){        //until we get a solution
          while(check(window.begin(),window.end(),K)){
              window.pop_front();       //shrink the window
          }
          //window.pop_front(last_val);   //now window is the tight and good.

          range = *max_element(w_itr-window.size(),w_itr+1)-*min_element(w_itr-window.size(),w_itr+1);
          if(range < minrange){
            minrange = range;
            lowerbound = *min_element(w_itr-window.size(),w_itr+1);
            upperbound = *max_element(w_itr-window.size(),w_itr+1);
          }

      }
  }

  cout<<"\nRange=("<<lowerbound<<","<<upperbound<<")"<<endl;
}

- Naresh Vankayalapati February 27, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The idea is, I merge the sorted arrays into a single bigger sorted array, like the last step in "merge sort" algorithm. While I do that I create a accompaining array with corresponding label of the original array. If we have K original arrays, the labels will be in the set {1...K}. Now, I push back each element from this accompaining array into a deque and perform a check*. If it passes the check, then I start to shrink the deque from front until it breaks the check. Here we have a tight window with atleast one of each of the integers 1...K. I use this state of the window to get the corresponding elements from the merged bigger sorted array and compute the range and lower/upper bounds. I repeat the process to find all possible range and lower/upper bound values and get the one that gives the least range.

*The check is to see if the deque has atleast one of each of the integers 1...K. To deal with repetitions, I simply put the elements into a set and check if the set is of size K.

- Naresh Vankayalapati February 27, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This makes me think of Suffix Tree.
Build up the tree, find the smallest common sub arr.

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

I think the best way to do it is to create a tree which once you print it in order gives all the elements of all the arrays sorted, then while creating that tree, for each element in the tree create a bit string which its size is the number of arrays and each bit says wether or not its contained by that array. At last pick the biggest numbers(they are contained by most of the arrays) and continue on their right and left until you fill your string with ones example(111111).
Later compare your intervals which you traversed to find their minimum:
Time complexity for creating the tree and the binaries for m arrays of size n:
O(m*n*log(m*n))
Time Complexity for traversing the fully sorted array and finding minimum interval(which it can be optimized) at worst case scenario is: O ((m)^2*n)
I'll write a code and post the link when I get the chance! but I don't think its necessary!

- Ramin March 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Previous comment is mine! :) Forgot to sign in! :D

- ramiGmodi March 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class ListOfArrays {
	ArrayList<ArrayList<Integer>> listArray;  // list of sorted arrays
	ArrayList<Integer> minIndexList;  // this list maintains the current index position within each array
	int minArray;
	boolean bFinal=false; 

	private class Interval {
		Integer min= Integer.MAX_VALUE, max=Integer.MIN_VALUE;
		boolean bFirst=true;


		void setMinInterval() {
			int low=Integer.MAX_VALUE,high=Integer.MIN_VALUE;
			for(int i=0;i<minIndexList.size();i++) {
				if(listArray.get(i).get(minIndexList.get(i))<low) {
					low=listArray.get(i).get(minIndexList.get(i));
					minArray=i;
				} 
				if(listArray.get(i).get(minIndexList.get(i))>high) {
					high=listArray.get(i).get(minIndexList.get(i));
				}
			}
			if((bFirst==true) || ((long) (high-low)<(long) (max - min))){
				min=low;
				max=high;
				bFirst=false;
			}
		}



		public String toString() {
			return String.format("[%d %d]", min, max);
		}
	}

	ListOfArrays(ArrayList<ArrayList<Integer>> arrays) {
		listArray=arrays;

	}

	/////////////////////
	//
	/////////////////////
	private void removeMin() {
		int i = minArray;
		if(minIndexList.get(i)<listArray.get(i).size()-1) {
			minIndexList.set(i, minIndexList.get(i)+1);
		} else {
			bFinal=true;
		}
	}

	////////////////
	//
	////////////////
	public Interval findMinRange() {

		Interval v = new Interval();


		minIndexList = new ArrayList<Integer>();



		// init index list to 0th element
		for(int i=0;i<listArray.size();i++){ minIndexList.add(0);}
		v.setMinInterval();
		while(bFinal!=true) {
			removeMin();
			v.setMinInterval();

		}

		return v;
	}



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

			2	10	20	53
			1	5	52	54
			23	24	53	55
			5	6	7	152
			24	28	50	152
			3	21	51 	53
		 */


		ArrayList<ArrayList<Integer>> arrays = new ArrayList<ArrayList<Integer>>();
		ArrayList<Integer> a,b,c,d,e,f ;
		a= new ArrayList<Integer>();
		a.add(2);a.add(10);a.add(20);a.add(53);

		b= new ArrayList<Integer>();
		b.add(1);b.add(5);b.add(52);b.add(54);

		c= new ArrayList<Integer>();
		c.add(23);c.add(24);c.add(53);c.add(55);

		d= new ArrayList<Integer>();
		d.add(5);d.add(6);d.add(7);d.add(52);

		e= new ArrayList<Integer>();
		e.add(24);e.add(28);e.add(50);e.add(52);

		f= new ArrayList<Integer>();
		f.add(3);f.add(21);f.add(51);f.add(53);

		arrays.add(a);arrays.add(b);arrays.add(c);
		arrays.add(d);arrays.add(e);arrays.add(f);
		ListOfArrays m = new ListOfArrays(arrays);
		Interval v = m.findMinRange();
		System.out.println("INPUT: "+arrays.toString());
		System.out.println("OUTPUT: "+v.toString());

	}

}

- jayswami March 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 votes

Here’s an explanation of my approach :

So let us say the 6 sorted arrays are:

2 10 20 25
1 5 6 7
23 24 25 26
5 6 7 8
24 28 50 52
3 21 51 53

initially we have 6 pointers on the 0th index of each array (2,1,23,5,24,3) <<
we find the interval of that set.. here it happens to be [1 24]



so range of {2,1,23,5,24,3} = [1 24]
we immediately remove the lowest element from the set, and insert the next element from that array.. in this case, 1.. w eincrement index of 2nd array.. next element is 5. So set becomes
{2,5,23,5,24,3} and range = [2 24] we replace the min_interval variable with [2 24] as 24-2 < 24-1

if we continue this, we get


2
1
23 [1 24] min = [1 24]
5
24
3

removeMin -> 1



2
5
23 [2 24] min = [2 24]
5
24
3
removeMin ->2

10
5
23 [3 24] min = [3 24]
5
24
3

removeMin ->3

10
5
23 [5 24] min = [5 24]
5
24
21

removeMin ->5

10
6
23 [5 24] min = [5 24]
5
24
21

removeMin ->5

10
6
23 [6 24] min = [6 24]
6
24
21

removeMin ->6


10
7
23 [6 24] min = [6 24]
6
24
21

removeMin -> 6

10
7
23 [7 24] min = [7 24]
7
24
21

after 2 time remove min 7

10
7 (last element)
23 [7 24] min = [7 24]
8
24
21

this is the terminating condition. the lower level cannot go above 7, and the max levels can only go up.. so [7 24] is the answer


new example

2 10 20 53
1 5 52 54
23 24 53 55
5 6 7 52
24 28 50 52
3 21 51 53

{(2,1,23,5,24,3), [1 24]} [1 24] -> {(2,5,23,5,24,3), [2 24]} [2 24] -> {(10,5,23,5,24,3), [3 24]} [3 24] -> {(10,5,23,5,24,21), [5 24]} [5 24]-> {(10,52,23,5,24,21), [5 24]}[5 24] ->{(10,52,23,6,24,21), [6 24]} [6 24]-> {(10,52,23,7,24,21), [7 24]}[7 24] ->{(10,52,23,52,24,21), [10 52]} [7 24] -> {(20,52,23,52,24,21), [20 52]}[7 24] ->{(53,52,23,52,24,21), [21 53]} [7 24] -> {(53,52,23,52,24,51), [23 53]}[7 24] -> {(53,52,24,52,24,51), [24 53]}[7 24] -> {(53,52,53,52,24,51), [24 53]}[7 24] -> (53,52,53,52,28,51), [28 53]}[7 24] -> (53,52,53,52,50,51),[50 53]}[50 53] -> (53,52,53,52,52,51),[51 53]}[51 53] -> (53,52,53,52,52,53),[52 53]}[52 53] -> (53,54,53,52,52,53),[52 54]}[52 53] ->
(53,54,54,52,52,53),[52 55]}[52 53] -> final solution [52 53]

Worst case running time = O(m * m* n)
can someone tell me what the average case running time would be? O (m*n) or O (n*mlgm) ?
worst case list of arrays would be m identical arrays.

- jayswami March 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I like your approach! I haven't been able to find anything wrong with it! But I think for big m and n my algorithm is better as the time complexity is m*n*log(m*n)! Also if the arrays keep changing my algorithm can keep track of that in almost linear time!
Still yours seems pretty damn good!
(Not Bad Face) :D

- ramiGmodi March 12, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

What if, instead of 7, the last element in the second array is 25

- Bhumika March 12, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>

template<class Iterator, class CONT2, typename FUNC>
Iterator SearchBound(Iterator beg, Iterator end, const CONT2& sorted, FUNC func) {
    if (beg == end) return beg;
    auto it = beg + std::distance(beg, end) / 2;
    if (it == beg) return beg;

    auto sv_beg = cbegin(sorted);
    auto sv_end = cend(sorted);
    while (sv_beg != sv_end) {
        if (func(cbegin(*sv_beg), cend(*sv_beg), *it) == cend(*sv_beg)) {
            return SearchBound(beg, it, sorted, func);
        }
        ++sv_beg;
    }
    return SearchBound(it, end, sorted, func);
}

void MinimumRange(const std::vector<std::vector<int> >& sorted_vec) {
    std::vector<int> vec;
    std::for_each(begin(sorted_vec), end(sorted_vec),
        [&vec](const std::vector<int>& c) {
        vec.insert(cend(vec), cbegin(c), cend(c));
    });
    std::sort(begin(vec), end(vec));
    vec.erase(std::unique(begin(vec), end(vec)), end(vec));

    auto beg = vec.cbegin();
    auto end = vec.cend();
    auto lower = SearchBound(beg, end, sorted_vec,
        [](decltype(beg) a, decltype(end) b, int c) { return std::lower_bound(a, b, c); });
    auto upper = SearchBound(beg, end, sorted_vec,
        [](decltype(beg) a, decltype(end) b, int c) { return std::upper_bound(a, b, c); });
    std::cout << "[" << *upper << ", " << *lower << "]" << std::endl;
}

- nishikenster July 26, 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