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

算法分析

考察例子:

 nums1[5]:  1   3   5   7   9 
nums2[7]: 2 4 6 8 10 12 14

1、题目要求算法复杂度为log(m+n) ,所以肯定不能考虑合并这两个数组;

2、考虑二分查找,考虑到已经排序,令k=(5+7)/2+1 ,比较nums1[k/2 - 1]nums2[k-k/2-1] 的大小,在这里即nums1[2]<nums2[3] ,所以中位数肯定不在nums[2] 的前一段。下一次就可以在nums1[3:5]nums2[0:7] 中查找,同时可以确定找到三个数nums[0:2] 小于中位数,故更新k=k-3;

3、k可以理解为比中位数小的数的数量,每次数组的一段被排除,这一段即小于中位数。k大于1的时候递归上述查找过程,当k等于1的时候,比中位数小的数的数量达到,即找到中间值。

*值得注意的是,两个数组的长度之和为偶数时,需要查找得到两个中位数,取平均。
这里写图片描述

C++实现

class Solution {
    typedef vector<int>::iterator Iter;

    int findMedianCore(Iter start1, int len1, Iter start2, int len2, int k) {
        if (len1 > len2)
            return findMedianCore(start2, len2, start1, len1, k);
        if (len1 == 0)
            return *(start2 + k - 1);
        if (k == 1)
            return min(*start1, *start2);

        int i1 = min(len1, k / 2);
        int i2 = k - i1;

        if ( *(start1 + i1 - 1) > *(start2 + i2 - 1) )
            return findMedianCore(start1, len1, start2 + i2, len2 - i2, k - i2);
        return findMedianCore(start1 + i1, len1 - i1, start2, len2, k - i1);
    }
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 = nums1.size();
        int len2 = nums2.size();
        if (!len1 && !len2)
            return 0;

        int k = (len1 + len2) / 2;
        int result1 = findMedianCore(nums1.begin(), len1, nums2.begin(), len2, k + 1);
        if ((len1 + len2) % 2 == 0) {
            int result2 = findMedianCore(nums1.begin(), len1, nums2.begin(), len2, k);
            return (double) (result1 + result2) / 2;
        }
        return result1;
    }
};

算法复杂度为O( log(m+n) ).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值