【高级编程技术】【作业】【第八周】【2】

LeetCode练习题

4. 两个排序数组的中位数

描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。
示例 1:

nums1 = [1, 3]
nums2 = [2]

中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

中位数是 (2 + 3)/2 = 2.5

思路

要求这么严格的时间复杂度,应该考虑二分求解。注意到这样一个事实:

nums1[0] nums1[1] ... nums1[i] | nums1[i+1] ... nums1[n]
nums2[0] nums2[1] ... nums2[j] | nums2[j+1] ... nums2[m]

如果分别把两个数组从上述位置切开,并满足如下条件:

  1. 左边数的个数=右边数的个数,即 (i+1)+(j+1)=(ni)+(mj) ( i + 1 ) + ( j + 1 ) = ( n − i ) + ( m − j )
  2. 左边的数均不大于右边的数,由于数组有序,即 max(nums1[i],nums2[j])min(nums1[i+1],nums2[j+1]) m a x ( n u m s 1 [ i ] , n u m s 2 [ j ] ) ⩽ m i n ( n u m s 1 [ i + 1 ] , n u m s 2 [ j + 1 ] )

那么中位数就由 nums1[i],nums2[j],nums1[i+1],nums2[j+1] n u m s 1 [ i ] , n u m s 2 [ j ] , n u m s 1 [ i + 1 ] , n u m s 2 [ j + 1 ] 这四个数确定。
因此只要二分 i i <script type="math/tex" id="MathJax-Element-4">i</script>即可。
需要注意一些特殊情况的判断。

代码

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        if len(nums1) > len(nums2):
            temps = nums1
            nums1 = nums2
            nums2 = temps
        if nums1 == []:
            return nums2[(len(nums2)-1)//2]/1 if len(nums2)%2 != 0 else (nums2[(len(nums2)-1)//2]+nums2[(len(nums2)-1)//2+1])/2
        nums1.insert(0, min(nums1[0], nums2[0])-1)
        nums2.insert(0, nums1[0])
        nums1.append(max(nums1[-1], nums2[-1])+1)
        nums2.append(nums1[-1])
        left1 = 1
        right1 = len(nums1)
        while left1 <= right1:
            middle1 = (left1+right1)//2
            middle2 = (len(nums1)+len(nums2))//2-middle1
            if nums1[middle1-1] > nums2[middle2]:
                right1 = middle1-1
            elif nums2[middle2-1] > nums1[middle1]:
                left1 = middle1+1
            else:
                break
        if (len(nums1)+len(nums2))%2 == 0:
            return (max(nums1[middle1-1], nums2[middle2-1])+min(nums1[middle1], nums2[middle2]))/2
        return min(nums1[middle1], nums2[middle2])/1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值