leetcode 第4题 Median of Two Sorted Arrays

算法分析:

对题目要求在已经排序好的两个数组之中寻找中位数,nums1的数组长度为m,nums2的数组长度为n,要求复杂度为O(log(m+n))例如:

输入:nums1 = [1, 3], nums2 = [2]

输出:2.0

输入:nums1 = [1, 2], nums2 = [3, 4]

输出:2.5

题目本身并不复杂,用传统的思维方法,一层循环就可以解决,但难点在于复杂度为O(log(m+n)),故用循环不可行


算法原理:

此题应该算是以前一到寻找第k位点的特殊情况:有有两个已经排序好的数组,寻找两个数组中排名第k个位置的数。
我们先分析原题的解法:要寻找第k个位置的数,只需要将两个数组中间的数从小到大排列,然后剔除掉前面k-1个数,剩下的第一个数便是结果所需要的值。
可以先设:
p = k/2 (整除)
q = k - p
先用nums1[p], nums2[q]进行比较,假设nums1[p] > nums2[q], 这就说明在两个数组整合过后的数组当中,nums2中的前q个数一定排在第k个数之前,这样nums2[0]到nums2[q]之间的数包括nums2[0]和nums2[q]全部可以剔除掉,则nums2可以重新生成新的数组n2,对于num1同理。这样我们在原数组中需要找的第k个数就变成了新生成过后的数组中 找的第k-q个数,这样,调用递归,将递归函数设置为Findmedian(nums1, n2, k-q)。中间的一些细节还需要特殊处理,此算法的复杂度为O(log(m+n))。


算法实现:

回到原题求中位数,经过上述的分析,可分成两种情况。
到m+n为奇数时,k = (m  + n)/2 +1,一次递归选择第k个数
到m+n为偶数时,k = (m + n)/2, 两个递归选择k个数,第k+1个数
基于Python的实现代码为:
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        m = len(nums1) + len(nums2)
        if m%2:
            return self.median(nums1, nums2, m//2+1) #为奇数时
        else:
            return (self.median(nums1, nums2, m//2) + self.median(nums1, nums2, m//2+1))/2 #为偶数时

    def median(self, n1, n2, k):
        if len(n1)==0:
            return n2[k-1]  #假如数组1等于0,那中位数便是在n2的第K个数,也就是n2[k-1]
        if len(n2)==0:
            return n1[k-1] #同理
        if k==1: #假如K只有一个数了,就取n1,n2中较小的那个
            if n1[0] > n2[0]:
                return n2[0]
            else:
                return n1[0]
        p = k//2
        q = k-p
        if p > len(n1): #分配过后的P值可能会大于n1的长度
            p = len(n1)
            q = k-p
        if q > len(n2):
            q = len(n2)
            p = k - q
        if n1[p-1] > n2[q-1]: #假如n1[p-1] > n2[q-1],那么就可以丢弃n2[0:q-1]的部分
            k-=q
            n2 = n2[q:]
        elif n1[p-1] < n2[q-1]:
            k-=p
            n1 = n1[p:]
        else:
            return n1[p-1]
        return self.median(n1, n2 ,k) #递归


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值