4. Median of Two Sorted Arrays两个有1序数组的中位数Python

有两个分别为大小m和n的排序数组nums1和nums2。

找到两个排序数组的中位数。总体运行时复杂度应为O(log(n+m))。 假设nums1和nums2不能都为空。 

 nums1nums2Median
A[2][]2
B[3][-2,-1]-1
C[1,3,4][-2,5,6]3.5

题中的中位数是相当于把nums1和nums2合并之后从小到大排序中间的数, 不考虑时间复杂度可以用sort函数自检:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        res = sorted(nums1 + nums2)
        l = len(res)//2  
        if len(res)%2==1:
            return res[l]
        else:
            return (res[l] + res[l- 1])/2

中位数就是如果两个list大小之和为奇数则取中间的数, 否则就取中间两个数加和除2。

运用到两个list中就是把nums1和nums2分成两部分其中第一部分的最大值小于第二部分的最小值

size加和为偶数
size加和为奇数

二分法: 首先要知道两个list长度和合并之后中位数所在位置。{l1=len(nums1); l2=len(nums2); l=(l1+l2+1)//2}

选取两个list中长度小的(nums1)进行操作, 设置一个min_index初始值为0, max_index初始值为小的list的长度。对nums1进行分区, 用i表示刚开始在nums1中间的位置,j则表示中位数前半部分选取了i个属于nums1的数字后, 剩余数字即属于nums2的数量。

{if l1>l2: nums1,nums2,l1,l2=nums2,nums1,l2,l1

min_index,max_index=0,l1

while min_index<=max_index:

i=(min_index+max_index)//2

j=l-i}

考虑到当i=l1时,nums1的后半部分则为空,且如果j=0时,则nums2的前半部分则为空,所以要比较一下两个list中的元素从右侧进行操作;如果i=0,j=l2则表示nums1的前半部分为空,nums2的后半部分为空,所以需要比较两个list元素大小从左侧进行操作。此外nums1或者nums2可能为空,所以要返回不为空的中间的值;都满足要求即左侧的最大值小于等于右侧的最小值则把左侧的最大值付给median变量。

{if i<l1 and j>0 and nums1[i]<nums2[j-1]: min_index+=1

elif i>0 and j<l2 and nums1[i-1]>nums2[j]: max_index-=1

else: if i==0: median=nums2[j-1]

       elif j==0: median=nums1[i-1]

       else: median=max(nums1[i-1], nums2[j-1])}

到现在为止已经找到中位数的位置,开始判断l1+l2是奇数还是偶数,如果是奇数,则返回median,如果是偶数数则返回median+右侧nums1和nums2的最小值加和除2,如果i=l1则nums1没有右侧部分所以返回median+nums2的右侧除2,j=l2同理。

{if (l1+l2)%2==1: return median

elif i==l1: return (median+nums2[j])/2

elif j==l2: return (median+nums1[i])/2

else: return (median+min(nums1[i],nums2[j]))/2}

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        l1=len(nums1)
        l2=len(nums2)
        if l1>l2:
            nums1,nums2,l1,l2=nums2,nums1,l2,l1
        l=(l1+l2+1)//2
        min_index=0
        max_index=l1
        while min_index<=max_index:
            i=(min_index+max_index)//2
            j=l-i
            if i<l1 and j>0 and nums2[j-1]>nums1[i]:
                min_index=i+1
            elif i>0 and j<l2 and nums1[i-1]>nums2[j]:
                max_index=i-1
            else:
                if i==0:
                    median=nums2[j-1]
                elif j==0:    #例如nums1=[1,2] nums2=[3,4]
                    median=nums1[i-1]    
                else:
                    median=max(nums1[i-1],nums2[j-1])
                if (l1+l2)%2==1:
                    return median
                elif i==l1:
                    return (median+nums2[j])/2
                elif j==l2:
                    return (median+nums1[i])/2
                else:
                    return (median+min(nums2[j],nums1[i]))/2

时间复杂度O(log(min(n,m)))因为是对两个list中size小的进行操作。

题目描述是关于寻找两个已排数组 `nums1` 和 `nums2` 的合并后的中位数。这两个数组分别包含 `m` 和 `n` 个元素。要解决这个问题,首先我们需要合并这两个数组并保持有,然后根据数组的总大小决定取中间值的方式。 1. 合并两个数组:由于数组是有的,我们可以使用双指针法,一个指向 `nums1` 的起始位置,另一个指向 `nums2` 的起始位置。比较两个指针所指元素的大小,将较小的那个放入一个新的合并数组中,同时移动对应指针。直到其中一个数组遍历完毕,再将另一个数组剩余的部分直接复制到合并数组中。 2. 计算中位数:如果合并数组的长度为奇数,则中位数就是最中间的那个元素;如果长度为偶数,则中位数是中间两个元素的平均值。我们可以通过检查数组长度的奇偶性来确定这一点。 下面是Python的一个基本解决方案: ```python def findMedianSortedArrays(nums1, nums2): merged = [] i, j = 0, 0 # Merge both arrays while i < len(nums1) and j < len(nums2): if nums1[i] < nums2[j]: merged.append(nums1[i]) i += 1 else: merged.append(nums2[j]) j += 1 # Append remaining elements from longer array while i < len(nums1): merged.append(nums1[i]) i += 1 while j < len(nums2): merged.append(nums2[j]) j += 1 # Calculate median length = len(merged) mid = length // 2 if length % 2 == 0: # If even, return average of middle two elements return (merged[mid - 1] + merged[mid]) / 2.0 else: # If odd, return middle element return merged[mid] ``` 这个函数返回的是两个数组合并后的中位数。注意,这里假设数组 `nums1` 和 `nums2` 都是非空的,并且已经按照升排列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值