二、Leetcode算法寻找两个有序数组的中位数

1、题目

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

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

2、分析

是将两个已经排序的列表进行合并,并找到中位数,但是题目要求了时间复杂度,所以需要在合并时排序方面进行选择,log首先会想到二分法,这样的话不会对全部的数据进行查找,这样时间复杂度会比较小,但是我在这里根据问题使用了类似二分法的改进版。每次去判断最后一位是否是一个小值,然后将之后的数全部合并,这样的话会节省大量的判断的时间,当然这里也可以使用sorted函数,这是我一开始没有想到的,最后发现使用sorted函数得分却是非常的高。

3、代码

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        x, y = 0, 0
        l = len(nums1)

        if (len(nums1) == 0 ) or (len(nums2) == 0):
            if len(nums1) == 0:
                return (nums2[int( len(nums2)/2 )] + nums2[ int( len(nums2)/2 - 1) ]) / 2 if len(nums2) & 1 == 0 else nums2[int( len(nums2)/2 - 0.5) ]
            if len(nums2) == 0:
                return (nums1[int( len(nums1)/2 )] + nums1[ int( len(nums1)/2 - 1) ]) / 2 if len(nums1) & 1 == 0 else nums1[int( len(nums1)/2 - 0.5) ]

        while True:
        # 全部插入到 nums1   
            if nums1[x] > nums2[y]:        
                nums1.insert(x, nums2[y])
                y += 1    
            if x+1 == len(nums1):
                x = x
            else:
                x = x+1
                
            if len(nums1) == l + len(nums2): # **
                break    
            # 这里代码的实现感觉是非常重要的,每次去判断最后一位是否是最小值
            # 然后将未插入的元素全部插入到这个值的后面
            # 极大的减少了判断元素的时间
            if nums1[-1] <= nums2[y]:    
                nums1 = nums1 + nums2[y:]
                
        return (nums1[int( len(nums1)/2 )] + nums1[ int( len(nums1)/2 - 1) ]) / 2 if len(nums1) & 1 == 0 else nums1[int( len(nums1)/2 - 0.5) ]
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
# 这里只是用三行代码就实现了要求
# sorted使用的是 timsort是一个稳定的排序函数,时间复杂度为 nlog(n)
		nums1 = nums1 + nums2
        nums1 = sorted(nums1)

	    return (nums1[int( len(nums1)/2 )] + nums1[ int( len(nums1)/2 - 1) ]) / 2 if len(nums1) & 1 == 0 else nums1[int( len(nums1)/2 - 0.5) ]

4、结果

# 第一种方法
执行用时 :108 ms, 在所有 python3 提交中击败了88.50% 的用户
内存消耗 :12.9 MB, 在所有 python3 提交中击败了99.43%的用户

# 第二种方法
执行用时 :104 ms, 在所有 python3 提交中击败了94.16% 的用户
内存消耗 :12.9 MB, 在所有 python3 提交中击败了99.43%的用户

5、改进
第一种感觉在判断一方为空时占用的时间比较多,没有将这一步的计算与大众的数据集成在一起,应该将if判断的代码优化一下,可能时间复杂度会更小,当然执行的用时也是根据随机数据随机计算的,不过在数据量小的情况下应该会比二分法速度要快。


望您:
“情深不寿,强极则辱,谦谦君子,温润如玉”。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值