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

 

解题思路:

这道题给出了两个已经排好序的数组,那么实际上就是用两个指针一起遍历两个数组,比较两个指针指向的数字大小,移动小的那个指针。

 

反思:

这道题虽然是hard的标签,但是我个人觉得并不算hard。

根据题目可以找到非常清晰的思路,但是我没有一遍通过。

主要问题出现在以下几点:

  1. typo, “==”是否是两个等号非常关键!

  2. 遍历数组时的指针需要检查是否超过数组长度!!!

 

代码:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int totalLen = nums1.size() + nums2.size();
        int mIdx2 = totalLen/2;
        int mIdx1 = totalLen & 1 ? -1 : mIdx2 - 1;
        int i1 = 0;
        int i2 = 0;
        int count = 0;
        double ret = 0;
        while(count <= mIdx2){
            int cur = 0;
            if(i1 >= nums1.size()){
                cur = nums2[i2];
                i2++;
            }else if(i2 >= nums2.size()){
                cur = nums1[i1];
                i1++;
            }else{
                if(nums1[i1] > nums2[i2]){
                    cur = nums2[i2];
                    i2++;
                }else{
                    cur = nums1[i1];
                    i1++;
                }
            }
            if(count == mIdx1)
                ret += (double)cur;
            else if(count == mIdx2)
                ret += (double)cur;
            count++;
        }
        return mIdx1 == -1 ? ret : ret/2.0;
    }
};

 

时隔一段时间又做到这题,发现自己之前太naive了。。。

题目要求要到log(m+n) 的复杂度

当时可能是瞎了吧 -,-

看了花花酱的解法

达到了O(log(min(m,n))) 的复杂度

// Author: Huahua
// Runtime: 52 ms
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        const int n1 = nums1.size();
        const int n2 = nums2.size();
        // Make sure n1 <= n2
        if (n1 > n2) return findMedianSortedArrays(nums2, nums1); // 因为要达到log(min(m,n))的复杂度,代表我们总是在最短的数组上做二分搜索
        
        const int k = (n1 + n2 + 1) / 2; //这样可以处理总数为偶数个的;
 
        int l = 0;
        int r = n1;
        // 开始二分搜索
     //
如果nums1[m1]的值比nums2[m2]的值要小,向右移动
     // 如果nums1[m1]的值比nums2[m2]的值大,向做移动
while (l < r) {
            const int m1 = l + (r - l) / 2;
            const int m2 = k - m1;
            if (nums1[m1] < nums2[m2 - 1])
                l = m1 + 1;
            else
                r = m1;
        }
        
        const int m1 = l;
        const int m2 = k - l;
        
        const int c1 = max(m1 <= 0 ? INT_MIN : nums1[m1 - 1], 
                           m2 <= 0 ? INT_MIN : nums2[m2 - 1]);
 
        if ((n1 + n2) % 2 == 1)
            return c1;    
        
        const int c2 = min(m1 >= n1 ? INT_MAX : nums1[m1], 
                           m2 >= n2 ? INT_MAX : nums2[m2]);
                
        return (c1 + c2) * 0.5;
    }
};

 

posted @ 2018-06-23 00:28  妖域大都督  阅读(121)  评论(0编辑  收藏  举报