求2个已排序数列的中值。leet的第一道hard题,其实可以用笨方法将2数组合并直接求中位数也能AC,但意义不大。网搜了下,该题算法逻辑还算好理解,用了类似二分法的思想,每次都可以剪一半的枝,但支持该算法的证明不是那么容易就能想到。要注意的是程序中k是现实中的序号,所以代码中要将k减去1以符合数组下标。
我只想说,这种题如果真的在面试时遇到,能有人真的从无到有一小时内证明理论并写出该算法吗?
合并求中位数的就不贴了,求kth的代码如下:
int smallerNumber(int a, int b) {
if (a < b)
return a;
else
return b;
}
int kthOfArray(int *nums1, int restSize1, int *nums2, int restSize2, int k) {
if (restSize1 > restSize2)
return kthOfArray(nums2, restSize2, nums1, restSize1, k);
if (restSize1 == 0)
return nums2[k - 1];
if (k == 1)
return smallerNumber(nums1[0], nums2[0]);
int ka = smallerNumber(k / 2, restSize1), kb = k - ka;
if (nums1[ka - 1] < nums2[kb - 1])
return kthOfArray(nums1 + ka, restSize1 - ka, nums2, restSize2, k - ka);
else if (nums1[ka - 1] > nums2[kb - 1])
return kthOfArray(nums1, restSize1, nums2 + kb, restSize2 - kb, k - kb);
else
return nums1[ka - 1];
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
double result = 0;
int k2 = (nums1Size + nums2Size);
if (k2 & 0x01)
result = kthOfArray(nums1, nums1Size, nums2, nums2Size, k2 / 2 + 1);
else
result = (kthOfArray(nums1, nums1Size, nums2, nums2Size, k2 / 2) + kthOfArray(nums1, nums1Size, nums2, nums2Size, k2 / 2 + 1)) / 2.0;
return result;
}