LeetCode Median of Two Sorted Arrays 解题报告 : 求解两个数组的中位数

LeetCode: Median of Two Sorted Arrays 解题报告

题目在此:https://leetcode.com/problems/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)).

 

You may assume nums1 and nums2 cannot be both empty.

题目大意:

给定两个已排序的两个数组nums1和nums2 ,大小分别为m和n,寻找数组nums1和nums2的中位数,总时间复杂度应为O(log(m+n)).

你可以假定两个数组非空。

 

Examples:

#1

nums1 = [1, 3]
nums2 = [2]
 
The median is 2.0

#2

nums1 = [1, 2]

nums2 = [3, 4]

 

The median is (2 + 3)/2 = 2.5

解决过程:

由于题目规定了时间复杂度为O(log(m+n)),因此应用一层循环解决以达到线性时间复杂度。

 

我们可以采用边遍历两个数组边寻找中位数的方法,将两个数组遍历合并拷贝到一个新数组,同时一边遍历一遍记录下当前已拷贝的数组中的中位数。

 

以下是代码实现:(Using C++,RUN TIME:64ms)

class Solution {
public:
    //假设两个数组都是有序递增的
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        auto it_a=nums1.begin(),it_b=nums2.begin();
        vector<int> t;
        int n=0;//用于记录已拷贝数组大小
        while (it_a != nums1.end() || it_b != nums2.end())
        {
            if(it_a==nums1.end())
            {
                t.push_back(*it_b);
                it_b++;
            }else if(it_b==nums2.end()){
                t.push_back(*it_a);
                it_a++;
            }else //若两个数组都未遍历到头,则拷贝两个数组迭代器指向的元素之中的较小者,保证拷贝后的数组t是有序递增的
                t.push_back(*it_a<*it_b?*it_a++:*it_b++);
            n++;
        }
        //如果数组大小是偶数,则中位数是由中心位置的两个数字取平均数而来
        if(n%2)
            return t[n/2];
        else
            return ((double)t[n/2-1]+t[n/2])/2;
    }
};

算法改进:

上述的算法可以这么改进:

如果当时我们遍历时直接遍历到中位数的位置上停止,那么数组t是不必要的,数组t的读写占一定的时间,因此数组t可以去掉。

使用该方法需要注意:当数组的大小是偶数,那么中位数的位置是(n1+n2)/2,如果数组的大小是奇数,那么中位数的位置是(n1+n2)/2+1,其中下标从1开始数起,n1,n2分别代表两个输入数组的大小。

以下是实现代码: (Using C++,Run TIME:32ms)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        auto it_a=nums1.begin(),it_b=nums2.begin();
        int n=0,ma;
        for(int i=1;i<=(nums1.size()+nums2.size())/2+(nums1.size()+nums2.size())%2;i++)
        {
            if(it_a==nums1.end())
                ma=*it_b++;
            else if(it_b==nums2.end())
                ma=*it_a++;
            else
                ma=*it_a<*it_b?*it_a++:*it_b++;
        }
        if(!((nums1.size()+nums2.size())%2))
        {
            if(it_a==nums1.end())
                return ((double)ma+*it_b)/2;
            else if(it_b==nums2.end())
                return ((double)ma+*it_a)/2;
            else
                return ((double)ma+(*it_a<*it_b?*it_a:*it_b))/2;
        }else
            return ma;
    }
};

 

暂时没有想到更好的优化方法,欢迎大家留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值