描述:
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)).
两个排好序的的数组找中位数,时间复杂度要求 O(log (m+n)).
如果把两个数组合并,排序再找中位数,显然时间复杂度是O(nlogn).
问题转换为求两个数组中第K个小的元素.参考http://blog.csdn.net/yutianzuijin/article/details/11499917/
首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。
当A[k/2-1]>B[k/2-1]时存在类似的结论。
当A[k/2-1]=B[k/2-1]时,我们已经找到了第k小的数,也即这个相等的元素.
- 如果A或者B为空,则直接返回B[k-1]或者A[k-1];
- 如果k为1,我们只需要返回A[0]和B[0]中的较小值;
- 如果A[k/2-1]=B[k/2-1],返回其中一个;
public class Solution { public static double findKth(int a[],int begina,int m,int b[],int beginb,int n,int k){ if(m>n) //确保函数m<=n return findKth(b,beginb,n,a,begina,m,k); if(m==0) return b[beginb+k-1]; if(k==1) return Math.min(a[begina],b[beginb]); int ma = Math.min(k / 2, m), mb = k - ma; //把k分成两部分 if(a[begina+ma-1]<b[beginb+mb-1]) //把a数组前面ma个元素去掉,第k小的元素不在这里 return findKth(a,begina+ma,m-ma,b,beginb,n,k-ma); else if(a[begina+ma-1]>b[beginb+mb-1]) //把b数组前面mb个元素去掉,第k小的元素不在这里 return findKth(a,begina,m,b,beginb+mb,n-mb,k-mb); else return a[begina+ma-1]; //相等时就是它 } public static double findMedianSortedArrays(int A[], int B[]) { int m=A.length; int n=B.length; int totalLength=m+n; if (totalLength%2 == 1) //奇数长度 return findKth(A, 0, m, B, 0, n, totalLength/2+1); else { //偶数长 return (findKth(A, 0, m, B, 0, n, totalLength / 2) + findKth(A, 0, m, B, 0, n, totalLength / 2 + 1)) / 2; } } public static void main(String[] args){ int[] a={3}; int[] b={1,2}; double median=findMedianSortedArrays(a,b); System.out.println(median); } }
View Java Code
http://blog.csdn.net/yutianzuijin/article/details/11499917/
时间: 2024-10-14 03:30:52