LeetCode:4. 寻找两个有序数组的中位数 python 实现

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。

方法一:利用sort排序

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
#         nums1.sort()#函数没有返回值
#         nums2.sort()
        while nums2 != []:
            nums1.append(nums2.pop())
        nums1.sort()
        if (len(nums1)%2) == 0:
            c1 = (nums1[len(nums1)//2] + nums1[(len(nums1)//2)-1])/2
        else:
            c1 = nums1[len(nums1)//2]
        return c1
        
 此方法利用排序直接寻找中位数,不解释。可以过,复杂度不符合要求

方法二:二分法

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if len(nums1) > len(nums2):
            nums1,nums2 = nums2,nums1  
        m = len(nums1)
        n = len(nums2)
        left = 0
        right = m
        while left <= right:
            i = (left + right) >> 1
            j = ((m + n + 1)>>1)-i
            nums1_left_max = float('-inf') if i == 0 else nums1[i-1]
            nums1_right_min = float('inf') if i == m else nums1[i]
            nums2_left_max = float('-inf') if j == 0 else nums2[j-1]
            nums2_right_min = float('inf') if j == n else nums2[j]

            if nums1_left_max <= nums2_right_min and nums1_right_min >= nums2_left_max:
                if m+n & 1:
                    return max(nums1_left_max,nums2_left_max)
                else:
                    return (max(nums1_left_max,nums2_left_max)+min(nums1_right_min,nums2_right_min))/2
            elif nums1_left_max > nums2_right_min:
                right = i-1
            else:
                left = i+1

二分法寻找中位数,复杂度也符合要求。
每个list分成左右两个部分
若两个list的元素个数之和为偶数,那么size左= size右
若两个list的元素个数之和为奇数,那么size左 = size右+1
list1左半部分的个数为i,list2左半部分的个数为j
且满足,i+j = (m+n+1)/ 2
然后在判断一下边界条件,因为有的时候一个list不需要分成两个部分,比如list1里的元素都小于list2的元素

方法三:双指针法

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if len(nums1) < len(nums2):
            nums1,nums2 = nums2,nums1
        m = len(nums1)
        n = len(nums2)
        s = m + n 
        p = 0
        q = 0
        if m < n:
            nums1,nums2 = nums2,nums1  
        while p<m and q<n:
            if p+q >=(s-1)//2:
                x = nums1[p]
                y = nums2[q]
                if x < y and p+1<m and nums1[p+1]<y:
                    y = nums1[p+1]
                if y<x and q+1<n and nums2[q+1] <x:
                    x =  nums2[q+1]
                if s&1:
                    return min(x,y)
                else:
                    return (x+y) /2
            elif nums1[p] > nums2[q]:
                q+=1
            else:
                p+=1
        while p+n <s//2:
            p+=1
        if s&1:
            return nums1[p]
        else:
            return (nums1[p]+nums1[p-1])/2
            

索引从0开始,依次比较两个list里元素的值,小的list 索引+1,再比较,记录比较次数,直至次数到中位数的位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值