There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
解法一: Merge first, and then find the median; O(m+n)
1 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { 2 int totalsize = nums1Size + nums2Size; 3 int *result = NULL; 4 int i = 0, j = 0, k = 0; 5 double ret; 6 7 if (totalsize == 0){ 8 return -1; 9 }else{ 10 result = (int *)malloc(totalsize * sizeof(int)); 11 } 12 13 if (result == NULL){ 14 return -1; 15 } 16 17 while( (i < nums1Size) && (j < nums2Size) ){ 18 if (nums1[i] < nums2[j]){ 19 result[k++] = nums1[i++]; 20 } else{ 21 result[k++] = nums2[j++]; 22 } 23 } 24 25 while (i < nums1Size){ 26 result[k++] = nums1[i++]; 27 } 28 29 while (j < nums2Size){ 30 result[k++] = nums2[j++]; 31 } 32 33 if ((totalsize % 2) == 1){ 34 ret = (double)(result[totalsize/2]); 35 }else{ 36 ret = (double)((result[totalsize/2] + result[totalsize/2 - 1])) /2; 37 } 38 39 free(result); 40 41 return ret; 42 }
解法二: Binary search; O(log(m+n))
"水中的鱼" (http://fisherlei.blogspot.com/search?q=median) 解释了如何用二分法做, 基本思想是在两个排序了的数组中求第K个数. 不过为何丢弃特定区间没有详细解释. 所以博主在这加以解释.
借用以上文章的图片, 其结论加以修正后附加上分析是 (简单的说,就是或者丢弃最大中位数的右区间,或者丢弃最小中位数的左区间).
1. If (m/2+n/2+1) >= k && a[m/2] >= b[n/2] , drop Section 2 以及 a[m/2];
推理过程: a[m/2] 大于等于 b[n/2]表明 小与等于a[m/2]的数至少有 a[0] 到a[m/2-1]和b[0]到b[n/2], 一共是(m/2 + n/2 +1)个, 这个数大于等于k. 这表明a[m/2]以及其后的在数组a里的数不可能是第k个数, 所以可以被丢弃.
2. If (m/2+n/2+1) >= k && a[m/2] <= b[n/2] , drop Section 4 以及b[n/2];
推理过程: 类似 1.
3. If (m/2+n/2+1) < k && a[m/2] <= b[n/2] , drop Section 1;
推理过程: a[m/2] <= b[n/2]表明大于等于a[m/2]的数有 a[m/2+1]到a[m-1]以及b[n/2]到[b[n-1], 一共是(m/2 - 1 + n/2)个. 然后 (m/2-1+n/2) = (m+n) - (m+n)/2 - 1 = (m+n) - (m/2+n/2+1) > (m+n) - k. 所以这意味着a[0]到a[m/2]之间的数不包括第K个数, 因为对第K个数来说, 大与等于它的数有(m+n)-K个. 结论是a[0]到a[m/2]这个区间的数可以被丢弃.
4. If (m/2+n/2+1) < k && a[m/2] >= b[n/2] , drop Section 3;
推理过程: 类似 3
1 int findKth(int a[], int m, int b[], int n, int k) /* m 以及 n 是数组的长度 */ 2 { 3 if (m <= 0) return b[k-1]; 4 if (n <= 0) return a[k-1]; 5 if (k <= 1) return (a[0] <= b[0]) ? a[0] : b[0]; 6 7 if ((n/2 + 1 + m/2) >= k) 8 { 9 if (b[n/2] >= a[m/2]) 10 return findKth(a, m, b, n/2, k); 11 else 12 return findKth(a, m/2,b, n, k); 13 } 14 else 15 { 16 if (b[n/2] >= a[m/2]) 17 return findKth(a + m/2 + 1, m - (m/2 + 1), b, n, k - (m/2 + 1)); 18 19 else 20 return findKth( a, m, b + n/2 + 1, n - (n/2 + 1), k - (n/2 + 1)); 21 } 22 } 23 24 double findMedianSortedArrays(int A[], int m, int B[], int n) { 25 if((n+m)%2 ==0) 26 { 27 return (findKth(A,m,B,n, (m+n)/2) + findKth(A,m,B,n, (m+n)/2+1))/2.0; 28 } 29 else{ 30 return findKth(A,m,B,n, (m+n)/2+1); 31 } 32 }