Median of Two Sorted Arrays

来源:互联网 发布:农村淘宝网址 编辑:程序博客网 时间:2024/06/10 03:41

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

这个题目,就是给出两段序列,然后找出这两段序列的中位数。但是有一个要求是时间复杂度要为O(log(m+n))

class Solution {public:    double findMedianSortedArrays(vector<int>& A, vector<int>& B) {        int m = A.size(), n = B.size();        int length=m+n;        if(length%2)return findkth(A, m, B, n, length/2+1);        else return (double(findkth(A, m, B, n, length/2))+findkth(A, m, B, n, length/2+1))/2;    }    int findkth(vector<int>& A,int m,vector<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 A[0]<B[0]?A[0]:B[0];        int pa=k/2<m?k/2:m;        int pb=k-pa;        if(A[pa-1]==B[pb-1]){return A[pa-1];}        if(A[pa-1]<B[pb-1]){            vector<int> num1;            for(int i = pa; i < m; i++){                num1.push_back(A[i]);            }            return findkth(num1, m-pa, B, pb, pb);        }                    else{            vector<int> num2;            for(int i = pb; i < n; i++){                num2.push_back(B[i]);            }            return findkth(A,pa,num2,n-pb,pa);        }                            }};

一看到有个log限制,所以就想到要用二分法了,从而也要用到递归。

主要说一下第二个函数findkth吧,这个函数就是给出两个序列及其长度还有第几个数,然后返回那个数。我选择把长的那段序列放在后面,短的放前面。长的为B,长度为n,短的为A,长度为m。若是m = 0,那么第k个数,即为B的第k个数,为B[k-1]。当k = 1时,就直接在A[0]和B[0]中选一个小的返回。若没有这条语句,则会导致后面无限递归,得不出答案。

一般来说是选择二分的,就是两条序列,都拿出k/2个数出来(这里我们可以让pa = k/2,pb = k - k/2,因为int类型会把后面的小数省去,比如说k = 15,那么k/2 = 7,这样,两个k/2相加就不是k了),然后让各自序列的第pa个和第pb个数进行比较。

若是相等,那就直接返回其中一个数就行了,因为第k个数就是两条序列的第个数。

若是A[pa] < B[pb] ,那么就说明,第k个数存在于A的pa——m,B的0——pb中,这时候又有两个新的序列了,要在这两个新序列中找到第pb个数,这个数即是原始序列的第k个数。

若是A[pa] > B[pb] ,那么就说明,第k个数存在于A的0——pa,B的pb——n中,这时候又有两个新的序列了,要在这两个新序列中找到第pa个数,这个数即是原始序列的第k个数。

这样就可以通过递归,继续往下寻找。

但当中有个问题,对于短的序列,可能总长度m比k/2要小,这样就要稍稍变通一下,让pa = min{m,k/2},pb = k - pa。


然后findMedianSortedArrays函数就注意一下总长度m+n是单还是双就行了,单数直接k = (m+n)/2 + 1,双数就找到第k = (m+n)/2 和第k + 1个数,然后加起来除以2就行。


呃呃呃,大概就是这样吧。这道hard的题,还是可以的,要不是时间复杂度有限制,我早就排个序,然后返回中位数了...



原创粉丝点击