Fish的Leetcode之旅——04 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)).

You may assume nums1 and nums2 cannot be both empty.

nums1 = [1, 3]
nums2 = [2]
The median is 2.0

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

题解

这个题算法课作业有过,但是只需要说思路,当时想的是分别对两个数组取中位数之后进行比较决定是向左面还是右面搜索,思路是正确的,不断的divide and conquer。但是实践起来向左和右的边界条件是很杂乱的。不知道如何是好,看了题解,记录一下。

两个数组共同的中位数可以将两个数组合并后的数组分为左右数量相等的两部分,对于两个数组A 和 B分别在i和j位置分,则可以将两个数组分为四个部分

A [ 0 ] ⋯ A [ i − 1 ] ∣ A [ i ] ⋯ A [ m − 1 ] A[0] \cdots A[i-1]|A[i]\cdots A[m-1] A[0]A[i1]A[i]A[m1]
B [ 0 ] ⋯ B [ j − 1 ] ∣ B [ j ] ⋯ B [ n − 1 ] B[0] \cdots B[j-1]|B[j]\cdots B[n-1] B[0]B[j1]B[j]B[n1]

要想满足找到中位数,需要有 i + j = m − i + n − j i+j=m-i+n-j i+j=mi+nj(两边数字个数相同)且 A [ i − 1 ] &lt; B [ j ]   a n d   A [ i ] &gt; B [ j − 1 ] A[i-1]&lt;B[j]\ and\ A[i]&gt;B[j-1] A[i1]<B[j] and A[i]>B[j1]那么此时当i确定时,j的位置也就唯一确定,此时判断上面的的条件即可,注意要满足 m &lt; n m&lt;n m<n的条件,否则会出现负数,同时对于边界条件若 i = 0 i=0 i=0有:

B [ 0 ] ⋯ B [ j − 1 ]   ∣   B [ j ] ⋯ B [ n − 1 ] , A [ 0 ] ⋯ A [ i − 1 ] ∣ A [ i ] ⋯ A [ m − 1 ] B[0] \cdots B[j-1]\ |\ B[j]\cdots B[n-1],A[0] \cdots A[i-1]|A[i]\cdots A[m-1] B[0]B[j1]  B[j]B[n1]A[0]A[i1]A[i]A[m1]

所以中位数的左面可以确定为 B [ j − 1 ] B[j-1] B[j1],同理 j = 0 j=0 j=0则左为 A [ i − 1 ] A[i-1] A[i1]
i = m 或 j = n i=m或j=n i=mj=n时可以确定右面分别是 B [ j ] 和 A [ i ] B[j]和A[i] B[j]A[i],考虑 m + n m+n m+n的奇偶性,可以得到最后的结果。查找i的位置使用二分查找,时间复杂度 O ( l o g n ) O(logn) O(logn)

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        
        m=len(nums1)
        n=len(nums2)
        if m>n:
            nums1,nums2,m,n=nums2,nums1,n,m #满足m<n
        imin,imax=0,m
        while imin<=imax:
            i=int((imin+imax)/2)#二分查找i的位置
            j=int((m+n+1)/2)-i
            if(i<m and nums2[j-1]>nums1[i]):#不满足条件则增大i此时j自动减小
                imin+=1
            elif(i>0 and nums1[i-1]>nums2[j]):#不满足条件则减小i此时j自动增大
                imax-=1
            else:#找到合适的i和j+边界判别
                if i==0:
                    left=nums2[j-1]
                elif j==0:
                    left=nums1[i-1]
                else:
                    left=max(nums1[i-1],nums2[j-1])
                if (m+n)%2!=0:
                    return left
                if i==m:
                    right=nums2[j]
                elif j==n:
                    right=nums1[i]
                else:
                    right=min(nums1[i],nums2[j])
                return float((left+right)/2.0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值