4.寻找两个有序数组的中位数 - 力扣(LeetCode)

我不喜欢这个世界,我只喜欢LeeCode

小夜斗打卡力扣刷题 day 6 ! 滴!

教育就是一棵树动摇另一棵树,一朵云推动另一朵云,一个灵魂唤醒另一个灵魂

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

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

前5天刷力扣的感觉是还行,咋到了第六天难度为困难就完全不行了!暴力求解还是能看懂,啥第k小数是真的看不懂!

  1. 暴力破解:先合并连个列表、利用sorted排序,最后找中位数
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums3 = sorted(nums1 + nums2)  # 合并并排序列表
        l = len(nums3)  # 合并后列表的长度
        if l % 2 == 0: # 偶数
        	# 返回中位数
            return (nums3[l//2-1] + nums3[l//2]) / 2
        else:  # 奇数
        	# 返回中位数
            return nums3[l//2]
  1. 第k小数解法:

没有思路目前,过两天回头再看看!

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        L = len(nums1) + len(nums2)  # 全部数字数量
        if(len(nums1) <len(nums2)):  # 如果列表nuns1短一些
            nums1, nums2 = nums2 , nums1  # 交换保持nums1比较长
        if L == 2:  # 总数量为2
            if len(nums2) == 0:  # 且nums2列表为空
            	# 直接返回nums1中位数平均值
                return (nums1[0] + nums1[1]) / 2.0
            # 否则返回nums2中位数平均值
            return (nums1[0] + nums2[0]) / 2.0
		
        if L%2 == 0: # 如果总数量为偶数
            EorO = True # flag 标志
            k = L // 2  # 第k小的数
        else: # 如果总数量为奇数
            EorO = False  # flag 标志
            k = L // 2 + 1  # 第k小的数
        print(EorO, k)  # 打印flag标志,与要找的第k小的数
        def helper(nums1,nums2,k): #本质上是找第k小的数
            if(len(nums1) <len(nums2) or (len(nums1) == len(nums2) and nums1[0] > nums2[0])):
                nums1, nums2 = nums2 , nums1 #保持nums1比较长;或者两个序列长度相等时,保持nums1[0]值最小
            if(len(nums2)==0): #递归返回条件之一,短序列nums2被剔空
                if EorO == True:
                    return (nums1[k-1] + nums1[k]) / 2.0 #二序列长度之和为偶数,取nums1的第k小和k-1小数
                else:
                    return nums1[k-1] #二序列长度之和为奇数,直接返回nums1的第k小数
            if(k==1): #递归返回条件之二,两个序列都有内容。二序列长度之和为偶数时,需判断很多边界条件。
                if EorO == True:
                    n1 = min(nums1[0], nums2[0]) #取出最小的首元素
                    if n1 == nums1[0]: #如果第一个序列的首元素最小
                        return (n1 + min(nums1[1], nums2[0])) / 2.0 #因为此时,二序列长度不为0,nums1至少有两个元素,nums2至少有1个元素
                    else: #如果nums2[0]最小
                        if len(nums2) > 1: #若nums2长度大于1,则取nums2[1]与nums1[0]的较小者与nums2[0]为所需结果
                            return (n1 + min(nums1[0], nums2[1])) / 2.0 
                        else: #若nums2长度为1,则取nums1[0]与nums2[0]为结果
                            return (n1 + nums1[0]) / 2.0
                else: #二序列长度之和为奇数
                    return min(nums1[0],nums2[0])  #找最小数,比较数组首位
            t = min(k//2,len(nums2)) # 保证不上溢
            if( nums1[t-1]>=nums2[t-1] ): #递归调用,即每次以新的k值和新的nums1(比较后的长序列)nums2(剔掉k/2个元素的新序列)作为递归调用参数
                return helper(nums1 , nums2[t:],k-t)
            else:
                return helper(nums1[t:],nums2,k-t)

        return helper(nums1, nums2, k)

上面寻找第k小的数这个代码小夜斗是真的没怎么看懂,但是不慌过几天就给它解决咯!

  • 在这个星球上,你很重要,请珍惜你的珍贵! ~~~夜斗小神社
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xtreallydance/article/details/113186236