leetcode刷题笔记04_寻找两个正序数组的中位数

题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。


示例

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5


解法一

可以直接合并数组,同时在合并的过程中找到第(m+n+1)/2的数,如果是偶数数组,还需要找到下一个数。合并的过程和第88题类似。该时间复杂度为O(m+n),不符合题要求。

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        p1=0
        p2=0
        x=0
        cur=0
        cur2=0
        m=len(nums1)
        n=len(nums2)
        while p1<m or p2<n:
            if p1==m:
                cur=nums2[p2]
                p2+=1
            elif p2==n:
                cur=nums1[p1]
                p1+=1
            elif nums1[p1]<nums2[p2]:
                cur=nums1[p1]
                p1+=1
            else:
                cur=nums2[p2] 
                p2+=1
            x+=1
            if (m+n)%2==1 and x==(m+n+1)/2:
                return cur
                break
            if (m+n)%2==0 and x==(m+n)/2:
                cur2=cur
            if (m+n)%2==0 and x==(m+n)/2+1:
                return (cur+cur2)/2

解法二

要达到O(log(M+N))的时间复杂度。需要使用二分查找的方法。

根据中位数的定义,当 m+n 是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n是偶数时,中位数是两个有序数组中的第 (m+n)/2个元素和第 (m+n)/2+1 个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1。

从而使用二分法,可以比较 A[k/2−1] 和B[k/2−1] 之后,可以排除 k/2 个不可能是第 k 小的数,查找范围缩小了一半。当k变成1时,比较指针当前指向的两个数,小的即为第k小的数。

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        def findindex(k):
            index1=0 
            index2=0
            while True:
                if index1==m:
                    return nums2[index2+k-1]
                if index2==n:
                    return nums1[index1+k-1]
                if k==1:
                    return min(nums1[index1],nums2[index2])
                newindex1=min(index1+k//2-1,m-1)
                newindex2=min(index2+k//2-1,n-1)
                if nums1[newindex1]<=nums2[newindex2]:
                    k-=newindex1-index1+1
                    index1=newindex1+1
                if nums1[newindex1]>nums2[newindex2]:
                    k-=newindex2-index2+1
                    index2=newindex2+1
        m=len(nums1)
        n=len(nums2)
        if (m+n)%2==0:
            return (findindex((m+n)//2)+findindex((m+n)//2+1))/2
        else:
            return findindex((m+n+1)//2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值