Leetcode第四题:寻找两个正序数组的中位数

题目:

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

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

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

 

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

个人思路:

没思路

官方答案推荐:

①求中位数可视为求第k小的数。计算出中位数所在位置k,每次取两数组k//2位置的数来比较,小的一方则为中位数前的部分数据,移出数组,更新k,继续循环比较。原理:A[k/2] 最多是第 k-1 小的数,所以可排除之前的数。

②使用分割法分割两个数组为四部分,使max(ALeftMax,BLeftMax)和min(ARightMin,BRightMin)之间的数为中位数。保证左右分割后长度相同,ALeftMax<BRightMin,BLeftMax<ARightMin。

奇偶的问题:可将数组拉伸成2x+1的长度,视为两数之间添入空数字,每个数/2可变回原来位置。割在数上两边各分一个,割在空数字上则正常左右分配。得到公式:LeftMax = (curIndex-1)/2,RightMin = curIndex/2。此时两数组长度和为2m+2n+2,找到m+n+1和m+n+2位置的数即可。代码实际使用时直接用公式,所以可当空数字不存在。

二分法:找个长度短的数组进行,设为A数组。则ALeftMax>BRightMin时,mid--,BLeftMax>ARightMin,mid++

python代码:

import sys
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums1Length = len(nums1)
        nums2Length = len(nums2)
        #保证nums1是短的
        if nums1Length > nums2Length:
            return self.findMedianSortedArrays(nums2,nums1)

        nums1LMax = nums2LMax = nums1RMin = nums2RMin = nums1Mid = nums2Mid = 0
        nums1Low = 0
        #放大成2倍
        nums1High = 2 * nums1Length
        while nums1Low <= nums1High:
            #总和是m+n+1个,mid为索引值
            nums1Mid = (nums1Low + nums1High)//2
            nums2Mid = nums1Length + nums2Length - nums1Mid
            #当某数组数值全在中值左边或右边时,代表中值肯定在另一数组,令LMax<RMin
            nums1LMax = -sys.maxsize if nums1Mid == 0 else nums1[(nums1Mid-1)//2]
            nums2LMax = -sys.maxsize if nums2Mid == 0 else nums2[(nums2Mid-1)//2]
            nums1RMin = sys.maxsize if nums1Mid == 2*nums1Length else nums1[nums1Mid//2]
            nums2RMin = sys.maxsize if nums2Mid == 2*nums2Length else nums2[nums2Mid//2]
            #二分查找
            if(nums1LMax > nums2RMin):
                nums1High = nums1Mid - 1
            elif(nums2LMax > nums1RMin):
                nums1Low = nums1Mid + 1
            else:
                break
        return (max(nums1LMax,nums2LMax)+min(nums1RMin,nums2RMin))/2

      

反思:

太难了。。。

保证A数组最短方法,判断长度,之后该函数参数的A、B互换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值