python3寻找两个有序数组的中位数[二分查找]

题目连接->

要求时间复杂度log(m+n)

官方题解很到位

"""
二分。
找到切割点

切割点 满足  left_max <= right_min

"""

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        return self.median(nums1, nums2)

    def median(self, A, B):
        m, n = len(A), len(B)
        if m > n:
            A, B, m, n = B, A, n, m
        if n == 0:
            raise ValueError

        #第一个列表的 切割点i, 
        imin, imax, half_len = 0, m, (m + n + 1) // 2
        
        while imin <= imax:
            i = (imin + imax) // 2 #中间
            j = half_len - i # 获取第二个数组的切割点j

                 
            if i < m and B[j-1] > A[i]:
                """
                A1, A2 |i|  A3, A4
                B1, B2 |j|  B3,B4

                如果A3 <B2 表示 i 小了
                """
                # i is too small, must increase it
                imin = i + 1
            elif i > 0 and A[i-1] > B[j]:
                
                """
                A1, A2 |i|  A3, A4
                B1, B2 |j|  B3,B4

                如果A2 > B3 表示 i 大了
                """
                
                # i is too big, must decrease it
                imax = i - 1
            
            else:
                #切割点满足 left_集合元素 <= right_集合元素
                # i is perfect

                if i == 0: max_of_left = B[j-1]
                elif j == 0: max_of_left = A[i-1]
                else: max_of_left = max(A[i-1], B[j-1])

                if (m + n) % 2 == 1: # 奇数长度的情况
                    return max_of_left

                if i == m: min_of_right = B[j]
                elif j == n: min_of_right = A[i]
                else: min_of_right = min(A[i], B[j])

                return (max_of_left + min_of_right) / 2.0


    

                """
                A1, A2 |i|  A3, A4
                B1, B2 |j|  B3,B4

                切割点i,j必须满足:
                B2 <=A3 and A2 <=B3 

                所以不符合条件的就是[命题的否定]
                B2 > A3 or A2 > B3 
                """        
    
   
            
            
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值