LeetCode No.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
====================================================================================================================================

这道题目的大意是:用时间复杂度为O(log (m+n))的算法找出两个大小分别为m和n的两个排序数组的中位数。

刚开始看到这道题的时候想到先把数组合并,再二分查找,二分查找的时间复杂度是O(log (m+n)),但合并数组的时间复杂度是O(m+n),所以总的时间复杂度应该是O(m+n),不符合题意,这种方法是行不通的。可是我想了很久都没能想出一种时间复杂度为O(log (m+n))的算法,最后在网上找到了一份题解看了一下(http://blog.csdn.net/zxzxy1988/article/details/8587244),总结如下:

该方法将寻找中位数的问题转成了寻找第K小的数的问题。按照这道题,当m+n为奇数时,中位数就是第(m+n)/2个数;当m+n为偶数时,中位数就是第(m+n)/2小的数和第(m+n)/2+1小的数的平均数。
至于寻找第K小的数,首先假设数组num1和num2的元素个数都大于k/2,我们比较num1[k/2-1]和num2[k/2-1]两个元素,这两个元素分别表示num1的第k/2小的元素和num2的第k/2小的元素。如果num1[k/2-1]<num2[k/2-1],这表示num1[0]到num1[k/2-1]的元素都在num1num2合并之后的前k小的元素中。也就是说,num1[k/2-1]一定比两数组合并之后的第k小值小,所以我们可以将其抛弃。对于num1[k/2-1]>num2[k/2-1]这种情况也类似。当两者相等时,第K小的数就是这个相等的数。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int sum = nums1.size() + nums2.size() ;
        if ( sum & 0x1 )
            return Kth(nums1, 0, nums1.size(), nums2, 0, nums2.size(), sum / 2 + 1) ;
        else
            return ( Kth(nums1, 0, nums1.size(), nums2, 0, nums2.size(), sum / 2 ) + Kth(nums1, 0, nums1.size(), nums2, 0, nums2.size(), sum / 2 + 1) ) / 2.0 ;
    }
    double Kth(vector<int>& nums1, int b1, int size1, vector<int>& nums2, int b2, int size2, int k )//b表示开始下标,size表示数组长度
    {  
        if ( size1 > size2 )// 保证nums1长度不大于nums2
            return Kth ( nums2, b2, size2, nums1, b1, size1, k ) ;
        if ( size1 == 0 )// 当size1为空时,第K小的数就是nums2中第K小的数
            return nums2[b2+k-1] ;
        if ( k == 1 )// 第一个数是nums1和nums2中第一个数的最小值
            return min ( nums1[b1], nums2[b2] ) ;
        int mid1 = min ( size1, k / 2 ) , mid2 = k - mid1 ;
        if ( nums1[b1+mid1-1] < nums2[b2+mid2-1] )
            return Kth ( nums1, b1 + mid1, size1 - mid1, nums2, b2, size2, k - mid1 ) ;
        else if ( nums1[b1+mid1-1] > nums2[b2+mid2-1] )
            return Kth ( nums1, b1, size1, nums2, b2 + mid2, size2 - mid2, k - mid2 ) ;
        else
            return nums1[b1+mid1-1] ;
    }
};

提交结果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值