Median of Two Sorted Arrays

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

  1. 寻找两个排序数组的中位数,一种简单方法就是直接合并成一个数组取中位数,但是题目要求复杂度为O(log(m+n)),因此不合题意。

  2. 另一种方法可以转换成求第K小的元素,题目求中位数,也就是求第(m+n)/2小的元素,可以使用一种类似二分法的思路。

  3. 这个算法使用了一个重要结论,如果A[k/2-1]小于B[k/2-1],那么A[0]~A[k/2-1]都小于合并之后第k小的元素。证明如下:


-假设A[k/2-1]比A和B合并排序后的第K个元素大,然后我们假定是第(k+1)个元素。因为它比B[k/2-1]要小,所以B[k/2-1]至少是第k+2个元素。所以在数组A中最多有k/2-1个比A[k/2-1]小,在数组B中最多有k/2-1个比A[k/2-1]小。整个一共最多有k-2个比A[k/2-1]小,而假定的是A[k/2-1]比排序合并后第K个元素大,所以A[k/2-1]不可能比合并后第k个元素大。

class Solution {
public:
    //第k小的数
    double findkth(vector<int>::iterator a,int m,
                vector<int>::iterator b,int n,
                int k)
    {
        if(m >  n)
            return findkth(b,n,a,m,k);//确保a比b元素少
        if(m == 0)
            return b[k-1];
        if(k == 1)
            return min(*a,*b);

        int pa = min(k/2,m),pb = k - pa;
        if(*(a + pa - 1) < *(b + pb -1))
            return findkth(a+pa,m-pa,b,n,k-pa);//剔除了pa个比k小的
        else if(*(a + pa -1) > *(b + pb -1))
            return findkth(a,m,b+pb,n-pb,k-pb);//剔除了pb个比k小的
        else
            return *(a+pa-1);
    }

    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int>::iterator a = nums1.begin();
        vector<int>::iterator b = nums2.begin();
        int total = nums1.size() + nums2.size();

        // 判断奇偶
        if(total%2==1)
            return findkth(a,nums1.size(),
                           b,nums2.size(),
                           total/2+1);
        else
            return (findkth(a,nums1.size(),
                           b,nums2.size(),
                           total/2) +
                    findkth(a,nums1.size(),

                    .size(),
       total/2 + 1))/2;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值