问题
题目:[leetcode-4-Median of Two Sorted Arrays]
思路
这个题目还是比较困哪的。
说一下基本的思路,这个题求两个有序数组的中位数。那么,我们给出一个更一般的办法,即求出两个有序数组的第k位数。
大致的思路是这样,各自考虑A[k/2-1]与B[k/2-1]。如果是朴素的[1,3,5],[2,4,6]这样的情形,那么各自[k/2-1]元素构成了有序数组合并之后的第k-1项和第k项。基于这个基本的思路去做的。
然后,采用了递归查找的思路。
• A[k/2-1] == B[k/2-1],直接返回两者均可
• A[k/2-1] > B[k/2-1],下面的情况反回来。
• A[k/2-1] < B[k/2-1],这种情况说明,A[0]-A[k/2-1]当中都不可能存在合并后的第k个元素。所以,可以从A[k/2]这个位置开始查找。
这个题目比较难的是,边界条件。
• 当 A 或 B 是空时,直接返回 B[k-1] 或 A[k-1];
• 当 k=1 是,返回 min(A[0], B[0]);
• 当 A[k/2-1] == B[k/2-1] 时,返回 A[k/2-1] 或 B[k/2-1]
下面代码实现中,前两种情况是把为空的情形全部转化为A为空的情形。
代码
int min(int a, int b) { return a<b?a:b; }
int find_kth( int* A, int m, int* B, int n, int k ) {
if( m > n ) return find_kth( B, n, A, m, k );
if( m == 0 ) return B[k-1];
if( k == 1 ) return min(A[0], B[0]);
int ia = min(k/2, m);
int ib = k - ia;
if( A[ia-1] == B[ib-1] ) return A[ia-1];
else if( A[ia-1] < B[ib-1] ) return find_kth( A + ia, m-ia, B, n, k-ia );
else return find_kth( A, m, B+ib, n-ib, k-ib );
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int total = nums1Size + nums2Size;
if( total & 0x1 ) {
return find_kth( nums1, nums1Size, nums2, nums2Size, total/2+1 );
}else {
return ( find_kth(nums1, nums1Size, nums2, nums2Size, total/2 ) +
find_kth(nums1, nums1Size, nums2, nums2Size, total/2 + 1) ) * 1.0 / 2;
}
}