vbs比较两个数组里的数的大小_「leetcode每日一题」4. 寻找两个正序数组的中位数...

ddedd91a8be41b6e4bf3e9b0b568acd4.png

题目:

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例:

nums1 = [1, 3]nums2 = [2]则中位数是 2.0

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

解法

题目意思简单易懂,就是从两个数组中找到中位数。第一眼看到这个题目想到的方法就是找到中位数是第k个,然后通过分别遍历每个数组找到第k个数,但是题目中有要求算法复杂度为O(log(m + n))。我们只能采取别的方法,看到log的复杂度就想到了二分查找,但是如果在两个数组中实现二分查找呢?

首先,二分查找要分两类讨论,如果是奇数个数组,就选出中间那个,如果是偶数个数字,就选出中间两个数求平均,这样我们的问题就转化成了找到两个数组中第K大的数。

寻找第K大的数也是通过二分查找来实现。我们先记录每个数组的起始位置,这可以方便我们在后面对K求二分时利用偏置,舍弃前面一半的数。将两个数组的起始位置都加上K/2,并确保数组不越界。比较这个位置两个数组中元素的大小,如果第一个数组小于第二个,表示第一个数组中该位置前面的数一定不会是第K个数,可以更新起始位置,并且更新K减去舍弃的数的个数,同理可得第二个数组。

通过不断更新K和起始位置,我们设定结束条件。如果一个数组走完了,那K数就在另一个数组中,直接取第K个,如果K等于1,比较两个数组中第一个数,选出结果。

代码

class Solution:    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:        def getKnum(k):            index1,index2 = 0,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(m-1,index1+k//2-1)                newindex2 = min(n-1,index2+k//2-1)                p1,p2 = nums1[newindex1],nums2[newindex2]                if p1 > p2:                    k -= newindex2 - index2 + 1                    index2 = newindex2 + 1                else:                    k -= newindex1 - index1 + 1                    index1 = newindex1 + 1        m,n = len(nums1),len(nums2)        totalnum = m + n        if totalnum % 2 == 1:            return getKnum((totalnum+1)//2)        else:            return (getKnum(totalnum//2)+getKnum(totalnum//2+1))/2

总结

简单的二分查找,通过在两个数组中做标记来实现二分的舍弃,受到很大启发。

如果文中存在一些错误,请多多指教。以后也会和大家分享leetcode每日一题的学习,希望大家多多支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值