【Leetcode】4. Median of Two Sorted Arrays 4. 寻找两个有序数组的中位数

1

解法

假如我们把A分成A[:i]A[i:]两部分,同理把B分成B[:j]B[j:]两部分
我们让A[:i]+B[:j]归为左边,A[i:]+B[j:]归为右边
如果:

  1. 左边和右边数字的个数相差不超过1
  2. 左边的数字全比右边小
    那么中位数将在左边的最大值和右边的最小值之间产生。

不妨令左边总是数量少的那方,即左边要么比右边少1,要么与右边相等。
很容易可以计算出,i+j==(m+n)//2
所以我们只需要搜索i或j其中一方即可。

对于满足上述条件的(i,j),我们还要让它满足条件2,那就需要:
A[i-1]<=B[j]B[j-1]<=A[i]

为了方便查找,我们总是假设m<=n,然后从0到m二分搜索i的值,搜索小的的好处是,由于在二分查找的过程中i不可能等于m,所以j也一定会在 ( 0 , n ) (0,n) (0,n)范围内,这说明B[j-1]B[j]都是有效的,省下了一次边界条件的判断。

查找的过程中如何移动呢?
首先很明显A[i-1]>B[j]B[j-1]>A[i]是互斥的

  • 如果A[i-1]>B[j],说明i太大了,要向小了搜
  • 如果B[j-1]>A[i],说明i太小了,要向大了搜

最后就是要注意边界条件的判断

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        if len(nums1)>len(nums2):
            nums1,nums2 = nums2,nums1
        m,n = len(nums1),len(nums2)
        odd = (m+n)%2!=0
        tar = (m+n)>>1
        l,r = 0,m
        def solve(i):
            j = tar-i
            if i==m:
                up = nums2[j]
            elif j==n:
                up = nums1[i]
            else:
                up = min(nums2[j],nums1[i])
            if odd:
                return up
            if j==0:
                down = nums1[i-1]
            elif i==0:
                down = nums2[j-1]
            else:
                down = max(nums1[i-1],nums2[j-1])
            return (up+down)/2.0
        while l<r:
            mid = (l+r)>>1
            if mid==0:
                if nums2[tar-1]>nums1[0]:
                    l = mid+1
                else:
                    return solve(mid)
            else:
                j = tar-mid
                if nums2[j-1]>nums1[mid]:
                    l = mid+1
                elif nums1[mid-1]>nums2[j]:
                    r = mid-1
                else:
                    return solve(mid)
        return solve(l)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值