[leetcode 2] Median of Two Sorted Arrays

来源:互联网 发布:微信淘宝联盟链接 编辑:程序博客网 时间:2024/06/07 11:43

题目:

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)).

思路:

1.如题目所述,A和B是各自排好序的数组,求这两个数组的中位数;
2.中位数:在一个数的集合中,中位数是这样一个数,集合中一半元素比它小,一半元素比它大;
3.本题目可等同于,在两个数组组成的数据集中找到第K大的数,K位置上的数为中位数;
4.求两个已排好序的数组的并集中第K大的数,则a中贡献pa个数,b中贡献pb个数,满足pa+pb=K;
5.考虑分布的均匀性及平等性,a贡献的数据应该与b贡献的数据一样多,那么可认为pa=pb=k/2;
6.于是求并集中第K大的数可以比较:a[k/2-1]与b[k/2-1];(减1是由于数组下标从0开始)
7.若a[k/2-1]<b[k/2-1],那么a中前k/2个元素即可直接舍弃,a[k/2-1]绝不会成为中位数,证明如下:
a.假设a[k/2-1]为中位数,那么在并集中a[k/2-1]应该属于第K个位置,在其前面应该有K-1个元素;
b.由于a[k/2-1]是中位数,那么在并集中中位数前由a贡献的元素有K/2-1个,且a[k/2-1]<b[k/2-1],那么在并集中由b贡献的元素至多为K/2-1个,a与b所贡献的元素个数之和至多为K/2-1+K/2-1=K-2个,也即中位数之前至多有K-2个元素,与中位数之前应该有K-1个元素矛盾;
c.综上所述,若a[k/2-1]<b[k/2-1],那么a中前K/2个元素可以直接舍弃,问题转化为在a剩下数据所组成数组与b组成的并集中求第K=K-K/2大的元素。
8.递归6、7步骤,直到a[k/2-1]==b[k/2-1],也即在并集中前K个元素中,a与b贡献的数据一样多,均为K/2,则a[k/2-1](b[k/2-1])即为中位数;
9.5----8四步根据均匀性以及平等性考虑,探索出类似于二分的算法,然而,在实际情况下,两个数组元素个数可能相差较大,如sizeof(a)=3,sizeof(b)=30,在求中位数的情况下,K=(3+30)/2=16,K/2=8,由于3<8,在并集中的前K个元素中,a并不能贡献K/2这么多的数据,而只能贡献3个,剩下13个数据均需b贡献,即选取pa的时候不能直接以K/2考虑,因为a中本身无这么多数据,所以选取pa时需要选取sizeof(a)与K/2中的较小值;
10.若经过递归,a(假设为较短数组)中已无元素,那么问题转变为K个元素均需b贡献,则返回b[k-1]即可;
11.若经过递归,K值变为1,那么问题转变为在a和b中求最小的值,由于数组已排序,那么直接求a[0]和b[0]的较小值即可;
12.改算法类似于二分,在m+n个数据中,每次砍掉K/2个数据,所以算法复杂度为O(logK),在求中位数问题中K=(m+n)/2,则复杂度为O(log(m+n))。

代码:

double findKth(int a[],int m,int b[],int n,int k){if(m>n)return findKth(b,n,a,m,k);if(m==0)return b[k-1];if(k==1)return min(a[0],b[0]);int pa=min(m,k/2);int pb=k-pa;if(a[pa-1]<b[pb-1])return findKth(a+pa,m-pa,b,n,k-pa);else if(a[pa-1]>b[pb-1])return findKth(a,m,b+pb,n-pb,k-pb);else if(a[pa-1]==b[pb-1])return a[pa-1];}class Solution{public:double findMedianSortedArrays(int A[],int m,int B[],int n){int total=m+n;if(total & 0x1){int k=total/2+1;return findKth(A,m,B,n,k);}else{int k=total/2+1;return (findKth(A,m,B,n,k-1)+findKth(A,m,B,n,k))/2;}}};



0 0
原创粉丝点击