Amazon Interview Question
Software Engineer / DevelopersCountry: United States
I think the same. Since in the statement is said "array of positive integers" probably they do not mean to just sort in nlogn.
@eugene: I agree, but I specified them. And I guess interviewer was looking for this approach as well as
otherwise it seems is not possible to come up with a solution for this!
@words&lyrics: You didn't specify the assumptions correctly. Your approach assumes that all elements are between [min, min + arr.length - 1]. How is that justified?
Please look at the solution again! Either I don't understand you or you missed something. Can you explain how I have assumed that?? I didn't intended
so please pinpoint it.
To my understanding, the sign of element at each position is used to indicate the repeating pattern. So negative means a number appears for odd number of times, and positive means appearing for even number of times. But what if a number never shows up? in that case, the sign is positive, how to catch this case?
yes it can be done in n.ln(n) time by using sorting. first sort the array and then you have to traverse the array once to count the number of appearances.
O(n) time O(1) Space
1. Find max and min
2. Traverse the array and for each a[i] change sign of a[[a[i]- min]]
Each time a element is found sign of location corresponding to that
(mapped to a[i]-min) changes sign. So same sign after this traversal means
even number of occurrences, different sign means odd no. of occurrences
3.Finally traverse the array from i =0 to i = max-min
and look for -ve element at location 'j'.
4. Return j+min
This algorithm will work only if all elements are of same sign initially
This assumes that all elements are between [min, min + arr.length]. This is blatantly false for most inputs.
I didn't understand what you mean! My only assumption was that they are of same sign. Can you
be more clear??
Please look again j can be between min and max-min
so j+min is between min to max, where min and max are minimum and maximum in the array
"Each time a element is found sign of location corresponding to that (mapped to a[i]-min) changes sign"
Why is a[i]-min necessarily in bounds? It's not, unless all a[i] are in the range [min, min + arr.length - 1]
"2. Traverse the array and for each a[i] change sign of a[[a[i]- min]]"
Again, same assumption.
I think the solution for specific ranges and the sorting solution pretty much cover it.
#include <math.h>
void main()
{
int a[] = {3,3,5,5,5,7,7,8,8,8,9,9,3};
for(int i = 0; i<13; i++)
{
if(a[abs(a[i])] > 0)
{
a[abs(a[i])] = -a[abs(a[i])];
}
else
{
a[abs(a[i])] = -a[abs(a[i])];
}
}
for(int i =0; i<13; i++)
{
if(a[abs(a[i])] > 0)
{
printf("\n even time %d ", abs(a[i]));
}
/* else
{
printf("\n odd time %d ", abs(a[i]));
}*/
}
}
Assuming the array can be sorted using standard C/C++ library functions here is the code to count the even number of occurring elements in the given array. It is better to ask the interviewer that the array can be sorted as suggested by some one in this thread.
void CountEvenOccurences(int *array,int length)
{
int prev_key = array[0];
int num_count = 1;
for (int i = 1; i < length; i++) {
int curr_key = array[i];
if (curr_key == prev_key) {
++num_count;
continue;
}
if ( (num_count %2) == 0 ) {
printf("Element %d occurs %d times.\n",prev_key,num_count);
}
prev_key = curr_key;
num_count = 1;
}
}
public class EvenlyRepeated {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Even repetation xor is " + (3 ^ 3 ^ 3 ^ 3));
System.out.println("Odd repetation xor is " + (2 ^ 2 ^ 2));
int[] values = { 1, 2, 3, 4, 1, 2, 3, 1, 2, 1 };
for (int i = 0; i < values.length; i++) {
int result = values[i];
for (int j = 0; j < values.length; j++) {
if (i != j && values[i] == values [j]) {
result = result ^ values[j];
}
}
if (0 == result) {
System.out.println(values[i]);
}
}
}
}
This works but prints repeated numbers every time it appears in array. This can be fixed by sorting array and then breaking loop on next number.
This is O(n^2) solution. Also you dont need xor here...for two numbers simple equality check will do..
//O(n log n) solution
public static void printOutEvenRepeats(int[] A) {
Arrays.sort(A); //O(n log n)
int currentNum = A[0];
int numSeen = 0;
for (int i = 0; i < A.length; i++) { // O(n) in worst case
// We see the same number
if (A[i]==currentNum) {
numSeen++;
if (i==A.length-1) {
if (numSeen != 0 && numSeen % 2 == 0)
System.out.println("We saw " + currentNum + " an even number of times.");
}
}
// The value at this array index is a different number. Reset numSeen and the currentNum
else {
if (numSeen != 0 && numSeen % 2 == 0)
System.out.println("We saw " + currentNum + " an even number of times.");
numSeen = 1;
currentNum = A[i];
}
}
}
It can be done without extra storage given the data has some bounds. Generally, if you have n elements and you are guaranteed that the elements are between 0 to n-1, we can use the value of the element itself as an "index" within the array and change the data to mark the item as read. For example, if a[i] =3, you can go to third index and multiply the value by -1 (a[3] * -1). But this requires the data to be bounded
- axecapone July 18, 2012