谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前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); } }