Amazon Interview Question for Software Engineer / Developers


Country: United States
Interview Type: In-Person




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

Take the XOR of all the numbers -- this is the XOR of the two missing numbers. Since they differ in at least 1 bit, the XOR is nonzero in at least 1 bit. Identify one such bit position.

Now, make a second pass through the array, XORing only numbers with that bit position set to 0 and ignoring the others. You will get one of the missing numbers as a result. Make a third pass that will consider only numbers with that bit position set to 1 to find the second missing number.

It's not apparent how to generalize this idea to 3 or more missing numbers, because 3 missing numbers that are all distinct could have an XOR of 0.

- eugene.yarovoi October 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If in the first pass, we find a value with multiple bit set to 1, then choose any one of such bit position.
This is really good answer without modifying the input array.

void twoNumAppearOnce(int arr[], int size)
{
  int i, val = 0, res1 = 0, res2 = 0;
  for (i = 0; i < size; i ++)
    val ^= arr[i];
  // Check if there are multiple bits are set to one choose any one of them.  I am choosing the right most set bit.
  if ( val & (val-1) )
    val = (val & (val-1));
  // Get the first number - that bit is off in number
  for ( i = 0; i < size; i ++ )
    if ((val & arr[i]) == 0)
      res1 ^= arr[i];
  // Get the second number - that bit is on in number
  for ( i = 0; i < size; i ++ )
    if ((val & arr[i])!=0)
      res2 ^= arr[i];
  printf ("Values are %d %d\n", res1, res2);
}

- Psycho October 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@eugene.yarovoi: your solutions are always with good explanation.Please continue the good work.

- aka[1] October 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

I think hashes are definitely needed. Thus you find all numbers appeared once in O(n) time. Some quick example below (in Ruby):

def find_single(ar)
    num_hash = Hash.new(2)
    ar.each do |n| 
        num_hash[n] -= 1
        num_hash.delete(n) if num_hash[n] <= 0
    end
        
    return num_hash.keys
end

- Andrei Zubov September 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 vote

2 numbers with single instance:

- XOR all the numbers.
- The final hash will have 2 numbers that occur only once 
- Go through the array XOR'ing each number with final hash and check whether the  
  remaining value is present in the array (we can use hashmap to improve lookup time). 
- We have our two numbers when the value is found.

I think the same logic can be extended to solve 3, .. 100 numbers.

- Chander October 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

>use hashmap to improve lookup time

If we use hashmap we do not need xor'ing elements anymore. Just loop over array, add current item to hashmap or delete it, if hashmap already contains it.

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

// only 1 number appears once and others twice

int unique_number(const vector<int>& a)
{
         int ans(0);
         for (int i=0; i < 32; i++) 
         {
                int b(0);
                for (int i=0; i < a.size(); i++)
                            b = ( b + ( a[i] & (1 << i) ? 1 : 0 ) ) %2 ; 
                if (b) ans |= (1 << i);
         }
         return ans;
}

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

If there's only 1 number appearing once, it's actually easier. just use xor. The duplicate values cancel out since their xor is 0

int unique_number(const vector<int>& a) {
	int ans(0);
	for (size_t i=0; i < a.size(); i++) 
		ans ^= a[i];
	return ans;
}

PS: you're using i in both nested loops

- Miguel Oliveira September 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

we can do this with XOR....suppose 2 elements are present one time....lets take an example
given array is {1,3,1,2,2,5,4,5} our output will be 3 and 4

step 1: XOR all elements...we get 3(XOR)4=111(in binary)
step 2: check first one in binary of XOR from right side....in our example first LSB is one....which means...LSB of required numbers is are not same.....
step 3: divide array in two parts..first part numbers has 1 at LSB and second part number has 0 at LSB

step 4: take XOR of first part we get first number and XOR of second part give second

our example
first part: 1(001),1(001),3(011) ,5(101), 5(101) .....XOR of these give 3
secont part: 2(010),2(010),4(100) XOR of these give 4

output: 3,4....which is required

i think for number more then 2 unique numbers..suppose for 10 unique numbers we have to divide array further to get all 10 element(for further division we can use other bits of xor)

- dhamu.31954 September 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good for 2 numbers, but three different numbers can give 0 if XORed each other: 7 xor 2 xor 5 = 0...and your approach does not work. I think another trick is needed here.

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

I think the idea is to use hash
if key exists then we remove it from hash else we add it to hash , as result the hash will remain just with those that are unique and is O(n)

- muntean.jenea October 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Suppose, if the same element repeated 3 times, then how can you handle? First time you will add, second time you will delete and third time again you will add... so, is my understanding right??? please correct me if i am wrong.

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

this solution work for n unique numbers and rest are twice.

- muntean.jenea October 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If we have some element repeated more then 2 times; we can do like this to get O(n) time using Hashing.
(1) check a number to add in a hash table,
if it is not there
then add number as key and value as 1
else then increment the value of that number by 1(by replacing old entry with new entry with increment value)
(2)When all numbers are added,
Traverse the HashTable to get keys whose value is 1.

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

we can do by using a set and an array, first add the elements one by one into set and into the array. If suppose any element is repeated then it will fail, when we try to add into set, then check if the same element is present in the array,if yes, then delete it from the array.

- Prashanth October 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

For 1 and 2 non repeating numbers cases XOR method is OK.

For 3 or more non-repeating numbers we have to use hashtable and for repetition we need to count the appearance. In final round we need to go through whole hash table and output the numbers which appeared exactly once.

- googlybhai October 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Seems like hashing or XORing are the two answers everyone here agrees on. I will go with the hashing since this kind of interview problem is usually given to test your knowledge of data structures (i.e. which one would work best and how)

So let's do this one in java real quick, using the obvious method, usually used for questions that ask for a fast way to find if a string contains duplicates (the principle can be applied to this without much adjustment).

public int[] find_unique(int[] a){
   HashMap<Integer, Integer> map = new HashMap<Integer,Integer>();
   for(int i = 0; i < a.length; i++){
      if(map.containsKey(a[i]) == true) map.put(a[i], map.get(a[i]) + 1);
      else map.put(a[i], 1);
   }
   ArrayList<Integer> uniques = new ArrayList<Integer>();
   for(int i = 0; i < a.length; i++){
      if(map.get(a[i]) == 1) uniques.add(a[i]);
   }
   return uniques.toArray();
}

Side note: not sure if the toArray I used would work in this case, whatever, you get the idea.

How it works: The method runs through and assesses the total count of all values in the original array. That takes O(n) time assuming the hashing function is decent. Then the method runs through again, after creating an initially empty arrayList, and any entry in a that has a stored value of 1 (meaning it was only seen once) is appended to the list. the list is then returned. The second half takes O(n) time, again assuming we have a decent hashing function.

This isn't as elegant as using logical operations, but you can get some brownie points in the interview if you mention that the runtime could potentially be O(n^2) if the hashing function is bad (i.e. tons of collisions).

- Anonymous October 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void findUniqueNumbers(int arg[], int length)
{
	map<int, int> numbers;
	map<int, int>::iterator it; 
	
	for(int i = 0; i < length; ++i)
	{
		++numbers[arg[i]];
	}
	for(it = numbers.begin(); it != numbers.end(); ++it)
	{
		if(it->second == 1)
			cout<<"unique number "<<it->first<<endl;
		
	}
	
}

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

Would it be wrong to use a hashset? Traversing through the array once, adding to the hashset when it doesn't contain the value and removing if it does contain it. Leaving you with a set at the end with only values that appeared once.

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

It's not wrong -- it's a general and extensible solution.

The reason for the XOR-based solutions is that these solutions can have a much lower constant factor, and the problem is trivial if you use a hash table, so one might think that a solution not based on hashing was desired.

- eugene.yarovoi October 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

how about writing a simple loop. O(n^2)

void finder(int a[],int size){
	int flag=0;
	for(int i=0;i<size;i++){
		flag=0;
		for(int j=0;j<size;j++){
			if(i==j)
				j++;
			if(a[i]==a[j]){
				flag=1;
				break;
			}

		}
		if(flag==0)
			cout<<a[i]<<"  is unique"<<endl;
	}

}

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

If there's more than one number appearing once, i think we need to use hashing.

- Miguel Oliveira September 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

ok, i didn't pick the right words. there are other ways but it gets much more complex than using a hashmap.
The hashmap approach is easy to code and yields a O(n) time and O(n) extra space solution. To the best of my knowledge, the other approaches take at least O(n) time and O(n) extra space, unless we can change the array inplace but it gets tricky.

Hence, i don't see any reason to not follow the hashing approach.

- Miguel Oliveira October 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 votes

@Miguel: check out my answer. I give an O(n) time, O(1) space method for finding two missing numbers without modifying the input array.

- eugene.yarovoi October 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

yes, it's similar to dhamu's answer, but for more numbers (if possible, i'm not sure, i didn't think about it properly) i think we need to split the numbers in groups depending on their lsb.

- Miguel Oliveira October 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

1. Sort all the elements. Duplicate elements will appear together.
2. Iterate the sorted elements to find out whether an elements is unique by performing equality test with previous one.

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

that's less efficient than hashing

- Miguel Oliveira September 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Why the downvote? I'm pretty sure the interviewer was looking for this answer instead of the hashing one.

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

i didn't downvote. i think it's more likely that the interviewer was looking into xor-based approaches instead of sorting or hashing, but this is a valid approach.

- Miguel Oliveira October 01, 2013 | Flag


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