I had an interview the other day with Amazon, and a question they asked me was pertaining to the following problem.
Given 2 integer arrays, containing any number of elem
The key is to sort the two arrays in-place. I did a search for "in-place radix sort", and found In-Place Radix Sort. I believe the problem is solvable, at least for Java int[], by applying those ideas to sort each array, bit by bit, then doing the obvious scan.
Incidentally, I think the correct output for the problem in the question code is 1, 2, 3.
Here is my implementation, based on the answers to the referenced question:
public class ArrayMatch {
public static void main(String[] args) {
int[] a = { 4, 1, 2, 3, 4 };
int[] b = { 2, 5, 6, 7, 3, 2, 2, 2, 2, 1, 2, 2, 2, 2 };
System.out.print("Original problem");
printMatches(a, b);
System.out.println();
int[] a1 = { 4, 1, -1234, 2, 3, 4, Integer.MIN_VALUE };
int[] b1 = { -1234, 2, 5, 6, 7, 3, 2, 2, 2, 2, 1, 2, 2, 2, 2 , Integer.MIN_VALUE, Integer.MAX_VALUE};
System.out.print("With negatives");
printMatches(a1, b1);
System.out.println();
}
// Print all matching elements between the two arrays.
private static void printMatches(int[] a, int[] b) {
if (a.length == 0 || b.length == 0) {
return;
}
sort(a);
sort(b);
int i = 0;
int j = 0;
while (true) {
while (a[i] < b[j]) {
i++;
if (i == a.length) {
return;
}
}
while (a[i] > b[j]) {
j++;
if (j == b.length) {
return;
}
}
if (a[i] == b[j]) {
System.out.print(" " + a[i]);
do {
i++;
} while (i < a.length && a[i - 1] == a[i]);
do {
j++;
} while (j < b.length && b[j - 1] == b[j]);
}
if (i == a.length || j == b.length) {
return;
}
}
}
// In place radix sort.
private static void sort(int[] in) {
// Flip the sign bit to regularize the sort order
flipBit(in, 31);
sort(in, 0, in.length, 31);
// Flip back the sign bit back to restore 2's complement
flipBit(in, 31);
}
/**
* Sort a subarray, elements start through end-1 of in, according to the
* values in firstBit through 0.
*
* @param in
* @param start
* @param end
* @param firstBit
*/
private static void sort(int[] in, int start, int end, int firstBit) {
if (start == end) {
return;
}
int mask = 1 << firstBit;
int zeroCount = 0;
for (int i = start; i < end; i++) {
if ((in[i] & mask) == 0) {
zeroCount++;
}
}
int elements = end - start;
int nextZeroIndex = start;
int nextOneIndex = start + zeroCount;
int split = nextOneIndex;
if (zeroCount > 0 && zeroCount < elements) {
while (nextZeroIndex < split) {
if ((in[nextZeroIndex] & mask) != 0) {
// Found a one bit in the zero area, look for its partner in the one
// area
while ((in[nextOneIndex] & mask) != 0) {
nextOneIndex++;
}
int temp = in[nextZeroIndex];
in[nextZeroIndex] = in[nextOneIndex];
in[nextOneIndex] = temp;
nextOneIndex++;
}
nextZeroIndex++;
}
}
if (firstBit > 0) {
sort(in, start, split, firstBit - 1);
sort(in, split, end, firstBit - 1);
}
}
private static void flipBit(int[] in, int bitNo) {
int mask = 1 << bitNo;
for (int i = 0; i < in.length; i++) {
in[i] ^= mask;
}
}
}