1.题目要求
There are two sorted arrays A and B 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)).
2.分析
这道题,首先需要理解中位数(Median)的定义。
举例:1,2,3的中位数是2,1,2,3,4的中位数是(2+3)/2=2.5。
弄清楚定义后,可以想出O(m+n)时间复杂度的算法,也就是两个下班分别指向A和B比较当前数A[i]和B[j],较小者的下标做自增操作,指导进行(m+n)/2次自增操作,或者某一个数组下标越界为止,代码如下:
1 class Solution { 2 public: 3 double findMedianSortedArrays(int A[], int m, int B[], int n) { 4 int middle ; 5 int temp = (m+n)%2; 6 if(temp == 1) 7 middle = (m+n)/2; 8 else 9 middle=(m+n)/2-1; 10 int i=0,j=0; 11 int count=0; 12 int flag=0; 13 double res; 14 while (count<middle&&i<m&&j<n) 15 { 16 if(A[i]<B[j]){ 17 i++; 18 } 19 else if (A[i]>B[j]) 20 { 21 j++; 22 }else 23 //当A[i]==B[j]时,两个数组下标移动需要取决于下一个数,比如{1,1}和{1,2}; 24 //1==1因此需要i++,如果是{1,2}和{1,1},则j++ 25 { 26 if(i+1<m&&A[i+1]==A[i]) 27 i++; 28 else if(j+1<n&&B[j+1]==B[j]) 29 j++; 30 else 31 i++; 32 33 34 } 35 count++; 36 } 37 38 if (i==m)//数组A已经越界 39 { 40 if(temp==0){ 41 res = (B[j+middle-count]+B[j+middle-count+1])/2.0; 42 }else 43 res = B[j+middle-count]; 44 45 }else if (j==n)//数组B已经越界 46 { 47 if(temp==0){ 48 res = (A[i+middle-count]+A[i+middle-count+1])/2.0; 49 }else 50 res = A[i+middle-count]; 51 }else 52 { 53 if (temp == 0) 54 { 55 if(i+1<m && A[i+1]<B[j]) 56 res = (A[i]+A[i+1])/2.0; 57 else if(j+1<n && B[j+1]<A[i]) 58 res = (B[j]+B[j+1])/2.0; 59 else 60 res = (B[j]+A[i])/2.0; 61 62 }else 63 { 64 res = A[i]>B[j] ? B[j]:A[i]; 65 } 66 } 67 68 return res; 69 70 } 71 };
提交代码,呵呵,能够Accepted。但是,题目要求时O(log(m+n)),因此我们需要想其他更好的算法,重点就是抓住sorted这个字眼。看到时间复杂度O(log(m+n)),我们会立刻想到二分查找思想,因此我们就按这个思路去寻找更好的算法。代码如下:
1 double findKth(int a[], int m, int b[], int n, int k) 2 { 3 //always assume that m is equal or smaller than n 4 if (m > n) 5 return findKth(b, n, a, m, k); 6 if (m == 0) 7 return b[k - 1]; 8 if (k == 1) 9 return min(a[0], b[0]); 10 //divide k into two parts 11 int pa = min(k / 2, m), pb = k - pa; 12 if (a[pa - 1] < b[pb - 1]) 13 return findKth(a + pa, m - pa, b, n, k - pa); 14 else if (a[pa - 1] > b[pb - 1]) 15 return findKth(a, m, b + pb, n - pb, k - pb); 16 else 17 return a[pa - 1]; 18 } 19 20 class Solution 21 { 22 public: 23 double findMedianSortedArrays(int A[], int m, int B[], int n) 24 { 25 int total = m + n; 26 if (total & 0x1) 27 return findKth(A, m, B, n, total / 2 + 1); 28 else 29 return (findKth(A, m, B, n, total / 2) 30 + findKth(A, m, B, n, total / 2 + 1)) / 2; 31 } 32 };