谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
分析:
“假设两个整数数组为A和B,各有N个元素,任意两个数的和组成的数组C有N^2个元素。
那么可以把这些和看成N个有序数列:
A[1]+B[1] <= A[1]+B[2] <= A[1]+B[3] <=…
A[2]+B[1] <= A[2]+B[2] <= A[2]+B[3] <=…
…
A[N]+B[1] <= A[N]+B[2] <= A[N]+B[3] <=…
问题转变成,在这N^2个有序数列里,找到前k小的元素”
//得到首中尾3个数的中位数
int getMidian(int array[], int low, int high) {
int mid = low + ((high - low) >> 1);
if (array[mid] > array[high]) {
swap(array[mid], array[high]);
}
if (array[low] > array[high]) {
swap(array[low], array[high]);
}
if (array[low] < array[mid]) {
swap(array[mid], array[low]);
}
return array[low];
}
int kth_elem(int array[], int low, int high, int th) {
int pivot = getMidian(array, low, high);
int lowTmp = low;
int highTmp = high;
while (lowTmp < highTmp) {
while (lowTmp < highTmp && array[highTmp] > pivot) {
highTmp--;
}
array[lowTmp] = array[highTmp];
while (lowTmp < highTmp && array[lowTmp] < pivot) {
lowTmp++;
}
array[highTmp] = array[lowTmp];
}
array[lowTmp] = pivot;
if (th - 1 == lowTmp) {
return array[lowTmp];
} else if (th - 1 < lowTmp) {
return kth_elem(array, low, lowTmp - 1, th);
} else {
return kth_elem(array, lowTmp + 1, high, th);
}
}