Interview Question
Game ProgrammersCountry: United States
Interview Type: Phone Interview
BST is not possible without a heuristic that reducing the array in half will yield the result. I don't see how BST is possible without sorting the array first.
1,1,7,7,3,3,19,19,4,10,10,11,11
It can be easily done by binary search
mid=6,so, arr[mid]=19,we see that 19 is not an answer, but one copy of 19 lies in right subarray, so right subarray must be of odd length, otherwise it contains the single element, so we go to left.(19,19,4,10,10,11,11)
Again notice that mid=9, arr[mid]=10.
but the array to the left contains 10 and is of odd length, so we go to left, i.e.
(19,19,4) becuase [19,19,4](arr[mid]=10)[10,11,11].
again arr[mid]=19, and array to the left is of odd length and contain 19 , so we go to right and eventually end up at 4.
this can be solved in O(n) and with no additional memory
public int find (int [] array){
int n = 0 ;
for (int v : array) {
n ^= v ;
}
return n ;
}
Im not sure if this is a correct algo for the problem. What will happen if input is {7, 7, 7, 4} or {7,7,7}?
This works if there is just only one non duplicate value which this is the case and all duplicates has a even number of dupes.
But it does not print duplicates. (although the question is not very clear)
Yeah, after looking around I saw the xor solution. Looking at mine it looks like my worst cast solution isn't actually n log n, it's n/2 in the worst case because I am jumping over each paired item so only needing to check half the elements.
I still don't see why they were pushing a BST or binary search solution.
You can get your answer in O(log n) time using binary search. Because all numbers except one come in pairs, you can divide the whole range in half, and then deduce the half your unique number belongs to. Here's C# code for that:
static int FindUnique(int[] values)
{
int pairCount = values.Length / 2 + 1;
return FindUnique(values, 0, pairCount - 1);
}
static int FindUnique(int[] values, int l, int r)
{
if (l == r)
return values[l * 2];
int m = l + (r - l) / 2;
if (values[m * 2] == values[m * 2 + 1] )
return FindUnique(values, m + 1, r);
else
return FindUnique(values, l, m);
}
/**
* Created by tiwariaa on 6/30/15.
*/
public class NonDuplicate {
static int pairs[] = {1, 1, 7, 7,8,8,99,99, 3, 3, 19, 19, 4, 10, 10, 11, 11, 15, 15, 2, 2};
static int index = 0;
public static boolean findDublicate(int lastNo, boolean flag){
if(pairs.length - 1 == index || flag){
return true;
}
index++;
if(index !=0 && index % 2 == 0){
return findDublicate(pairs[index], false);
}else{
if(lastNo != pairs[index])
return true;
return findDublicate(pairs[index], false);
}
}
public static void main(String[] ate) {
findDublicate(pairs[index], false);
System.out.println("---------->" + pairs[index -1]);
}
}
Since there is only 1 number without a pair, the array size is always odd. We can start with the middle. If the middle number is different from its neighbors, it's the number without the pair.
Here is the code I come up with in C#.
- DVD June 30, 2015