Median of Two Sorted Arrays

18 篇文章 0 订阅
1 篇文章 0 订阅

LeetCode上的一道题目,有点意思,求两有序数组放一块以后的中位数,复杂度要求O(log(n+m))

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(n))。而一个有序数组求他中位数基本就是O(1)。

现在是两个有序数组,结合二分的思路稍微要用点技巧,我的做法可以叫做二分排除法。

我们要求两数组合并后那个中间的一个数或两个数,即取第K小值问题。



上图中a到c和d到f都是有序的,ab和de长都为k/2。如果b处的数比e处的数小,说明什么,说明那个第K小的数一定不在ab之间,把ab裁掉拿bc重复操作,最终就能找到中位数。

以下是Python的实现。实现过程中还要注意一点,如果是用C/C++写的话,递归时候直接数组头一跳就变成新参数了。而Python中的切片操作本身复杂度是O(k)的,所以我采用index后跳的方式,模仿C里的数组头后跳。还有len()方法是O(1)的,可以大胆用。


class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        k_1 = (len(nums1) + len(nums2)+1)/2
        k_2 = (len(nums1) + len(nums2)+2)/2
        med_1 = self.search_k_th(nums1, 0, nums2, 0, k_1)
        med_2 = self.search_k_th(nums1, 0, nums2, 0, k_2)
        return (med_1 + med_2)/2.0
        
            
            
    def search_k_th(self, nums_1, head_1, nums_2, head_2, k):
        if head_1 == len(nums_1):
            return nums_2[head_2+k-1]
        elif head_2 == len(nums_2):
            return nums_1[head_1+k-1]
        elif k == 1:
            return min(nums_1[head_1], nums_2[head_2])
        
        step_1 = min(k/2, len(nums_1)-head_1)
        step_2 = min(k/2, len(nums_2)-head_2)
        if nums_1[head_1+step_1-1] < nums_2[head_2+step_2-1]:
            return self.search_k_th(nums_1, head_1+step_1, nums_2, head_2, k-step_1)
        else:
            return self.search_k_th(nums_1, head_1, nums_2, head_2+step_2, k-step_2)
            


这道题也提醒我应该关注一下Python内置函数的复杂度。Python Wiki上有





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值