Interview Question


Country: United States




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

I could not find a way to resolve this question with the info provided without sorting the array/list first, and then finding the missing values from 1 - k-1 (assume MergeSort O(nLogn) followed by a scan of O(n)
Simply put, you cannot have an array of size K and the elements are 1-K-1
Example: K=5
Array {3,2,1,4, ??? } <-- It can't be 0 (>1), and it can't be 5 (<= k-1), and size of array = 4 not 5

Also, let's say that the OP did not write the question properly, and K is not the size of the array but the max value in the array
For example: {3,2,5,7}
Then K = 7 and the missing values are {1,4,6}. In this case, the array has to be scanned to get K, then processed to find missing values. 2*O(n)

Or let's say K is provided as input, then a valid input with K = 100 is array = {1}...
98 missing numbers.

Regardless, here's my solution that runs in 2*O(n). The assumptions I made:
1. K is provided is part of the input.
2. Missing elements are only one-apart from existing elements. For example
K = 13
Input is { 1,8,3,5,7,6,2,11,12}
Output would be {9,4,10}
I didn't test for edge cases by the way...

Code

public class FindMissing {

	private HashMap<Integer, Boolean> tracker;
	
	
	public List<Integer> findMissing(List<Integer> input, int K)
	{
		if(input == null) { throw new IllegalArgumentException();}
		this.tracker = new HashMap<>();
		//O(n)
		for(int i = 0; i < input.size();i++)
		{
			Integer current, previous, next;
			
			current = input.get(i);
			//Make sure we stay within the bounds of 1 - K-1
			if(current > 1)
				previous = current-1;
			else
				previous = null;
			if(current < K-1)
				next = current+1;
			else
				next = null;
			
			//Algorithm:
			//When inspecting an entry in the input list, if the entry doesn't exist, insert it with value true (found)
			//Check if the previous (-1) and next (+1) elements exist and insert with false, otherwise do nothing.
						
			if(tracker.containsKey(current) == false) //New entry.
			{
				tracker.put(current,true);
				if(previous != null)
				{
					if(tracker.containsKey(previous) ==false)
						tracker.put(previous, false);
				}
				if(next != null)
				{
					if(tracker.containsKey(next) == false)
						tracker.put(next, false);
				}
			}
			else //we have encountered this key before
			{
				tracker.put(current, true); //Update to 'found'
				
				if(previous != null)
				{
					if(tracker.containsKey(previous)==false) 
						tracker.put(previous, false); 
				}
				if(next != null)
				{
					if(tracker.containsKey(next)==false)
						tracker.put(next, false);
				}
				
			}
		}
		
		//Another O(n) to find the missing elements
		List<Integer> missing = new ArrayList<>();
		Iterator iter = tracker.entrySet().iterator();
		Map.Entry<Integer, Boolean> entry = null;
		while(iter.hasNext())
		{
			entry = (Entry<Integer, Boolean>) iter.next();
			if(entry.getValue() == false)
				missing.add(entry.getKey());
		}
		
		return missing;
		
		
	}

}

And the driver code

List<Integer> input = new ArrayList();
		input.add(1);
		input.add(8);
		input.add(3);
		input.add(5);
		input.add(7);
		input.add(6);
		input.add(2);
		input.add(11);
		input.add(12);
		
		FindMissing find = new FindMissing();
		List<Integer> missing = find.findMissing(input, 13); //K = 13, so elements are expected to be 1-12
		System.out.println(missing.toString());

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

Nice fayezelfar
Your analysis good i.e K is provided is part of the input.

- HimanshuP January 19, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Aside from edge cases, this should be a good general solution. thx

- william.brandon.lee83 January 20, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

what do you mean missing elements in array? maybe, missing elements in arithmetic progression?

- zr.roman January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi zr.roman, no dude
You are given a list of n-1 integers and these integers are in the range of 1 to n. There are no duplicates in list. More than 1 of the integers is missing in the list

- HimanshuP January 17, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

counting sort can do this.

- zr.roman January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

This post discusses 2 solutions: Sum and Xor.
capacode. com/array/find-missing-number-in-array/

- anon January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Dude I'm not asking there is one number in the range from 0 to N missing.
I'm asking more than one element missing from 0 to n .
Please understand :-( :-(

- HimanshuP January 17, 2016 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

hi, sorry, my bad! I didn't read it carefully.

Anyway, here is my thinking.
If you have O(n) space available, then do a simple counting, then check for entries with zero count:

init Count[i] = 0 for all i.

for (i=0..size(A)-1) Count[A[i]]++

for (i=0..n-1) if Count[i] ==0: print i

If you are restricted to use only a constant extra memory (except the array itself), then you need to sort the array in-place. Unfortunately, I don't see any in-place sorting algorithm that runs in linear time. So, probably quick-sort is good choice.

After sorting in-place, just check pairs of adjacent elements in array, if they differ more than 1, the numbers between them are missing.

I doubt that O(n) time O(1) space algorithm exists.

So, either O(n) time O(n) space algorithm, or O(1) space O(nlogn) time algorithm exists.

Tell me if I am wrong.

- anon January 18, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This post discusses 2 solutions: Sum and Xor.
capacode. com/array/find-missing-number-in-array/

- anon9999 January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can we use radix sort?

- EPavlova January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

well, why not just substract the current int with the previous one (ie. n - (n-1))? if the diff is more than 1, there is one missing in between.

- nlnguyen70 January 17, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

the array is unsorted by default.

- zr.roman January 17, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Sorry - thought that the array is sorted, if it is solution is way straightforward :)

def find_miss(a):
    k = len(a)
    ctr = 1
    seq = 1
    while(ctr < k):
        if(a[ctr] != seq):
            print(seq)
            seq = seq + 1
        ctr = ctr + 1
        seq = seq + 1
          

    
a = [0,1,2,3,5,7,8,9,11]
find_miss(a)

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

ok in theory if you know a1+a2+..ak, a1^ a1 + a2^a2 + a3^a3 +a4^a4+...ak^ak,.....
a1^k+....ak^k, you will get a1,a2....ak when you solve this equation in some way.
a1+....ak is n*(n+1)/2 - sum_of_array, a1^ a1 + a2^a2 + a3^a3 +a4^a4+...ak^ak is n*(n+1)*(2n+1)/6 - sum of cubes of array elements... sum of powers - there is a formule which convert to polinom of n - sum of k-th degree of array items
I personally prefer to avoid such calculation and to sort array with O(n) complexity.

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

def find_missing(l):
  l =sorted(l)
  min = l[0]
  max = l[len(l)-1]
  tmp = []
  while min<=max:
    tmp.append(min)
    min+=1
  return sorted(list(set(tmp) - set(l)))

- Thanh Liem Tran January 18, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void findMissingEle(int iArr[K])
{
	int resArr[K]={0};
	for(int i=0;i<K;i++)
		resArr[iArr[i]] =iArr[i];
	cout << "\n missing elements are :";
	for(int i=0;i<K;i++)
	{
		if(resArr[i]==0)
			cout << i ;
	}
}

- sv January 21, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

It could be solved by counting sort:
1. find the min and max of the elements in the array
2. create any array of size max and init each element to 0
3. use counting sort to get the occurrence of elements in the array
4. check the new array from position min to max, the position of zero are the missing numbers

- runwithfullspeed February 02, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is easy to do with a boolean array of size n. loop from i = 0 to n and anytime an element appears set that value to true. You can solve this problem for any arbitrary number of missing elements by scanning the array exactly once. It uses O(n) space and time.

- Anonymous February 07, 2016 | 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