(leetcode 4)(python)寻找两个有序数组的中位数

一、前言

leetcode做的一道比较难的题,主要是算法有关的知识掌握不牢。
题目如下:
在这里插入图片描述
题目里默认有两个数组均为从小到大排列,如果不放心可以加一段比较两个元素然后逆序的过程后再运算。

二、思路

寻找两个有序数组的中位数,可以转变为求两个有序数组中第k小的数的问题:
1、当两个数组中元素个数为奇数n时,中位数即为第(n-1)/2小的数。
2、当两个数组中元素个数为偶数n时,中位数即为第n/2小的数和第(n/2)-1小的数的平均数。

求两个有序数组第k小的数求解思路有两种:
法1、假设两个数组第一个数字分别为m、n,比较哪个小就去掉哪个,一直找到第k个数,但时间复杂度为O(k),不太符合题目要求。
法2、二分法。
因为要求第k小,所以需要找一个边界,左边都比右边的数小,且左边有k个元素。左边最大的元素就是我们需要的数。时间复杂度为O(log(m+n))。
思路学习于这篇文章,笔者手写的代码。


def gets(nums):
    l=len(nums)
    if l%2==0:
        return ((nums[l//2-1]+nums[l//2])/2)
    else:
        return (nums[(l-1)//2])

def find(nums1,nums2,k):
    l1,l2=len(nums1),len(nums2)
    #k恰好处于两端,可直接返回
    if k==l1+l2:
        return max(nums1[l1-1],nums2[l2-1])
    elif k==1:
        return min(nums1[0],nums2[0])
    #两个数组没有重叠,可直接返回
    if nums1[0]>=nums2[l2-1]:
        if l2>=k:
            return nums2[k-1]
        else:
            return nums1[k-l2-1]
    elif nums2[0]>=nums1[l1-1]:
        if l1>=k:
            return nums1[k-1]
        else:
            return nums2[k-l1-1]
    #两个数组有重叠,获取两个边界c1、c2的初始值
    if l1<l2:
        c1=l1//2
        c2=k-c1
    else:
        c2=l2//2
        c1=k-c2
    if c1==0:
        c1+=1
        c2-=1
    elif c2==0:
        c1-=1
        c2+=1
    while(1):
    	#左右边界判断
        if c1==0:
            return nums2[k-1]
        elif c2==0 :
            return nums1[k-1]

        if c1==l1:
            if nums1[c1-1]>nums2[c2]:
                c1-=1
                c2+=1
                continue
            else:
                return max(nums1[c1-1],nums2[c2-1])
        elif c2==l2:
            if nums2[c2-1]>nums1[c1]:
                c2-=1
                c1+=1
                continue
            else:
                return max(nums1[c1-1],nums2[c2-1])
		#核心边界移动代码
        if nums1[c1-1]<=nums2[c2] and nums2[c2-1]<=nums1[c1]:
            return max(nums1[c1-1],nums2[c2-1])
        elif nums1[c1-1]>nums2[c2]:
            c1-=1
            c2+=1
        elif nums2[c2-1]>nums1[c1]:
            c1+=1
            c2-=1
            continue
    return ;


class Solution:
    def findMedianSortedArrays(self, nums1, nums2) :
        l1,l2=len(nums1),len(nums2)
        if l1==0:
            return 0.0+gets(nums2)
        elif l2==0:
            return 0.0+gets(nums1)
        if (l1+l2)%2==0:
            x,y=(l1+l2)//2,(l1+l2)//2+1
            return 0.0+(find(nums1[0:x],nums2[0:x],x)+find(nums1[0:y],nums2[0:y],y))/2
        else:
            z=(l1+l2-1)//2+1
            return 0.0+find(nums1[0:z],nums2[0:z],z)


if __name__=="__main__":
    nums1,nums2=[3,4],[1,2]
    a=Solution()
    ret=a.findMedianSortedArrays(nums1, nums2)
    print(ret)
    

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值