[leetcode]4. 寻找两个正序数组的中位数

1.题目

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

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

分析:

# m+n偶数: ((m+n)/2 + (m+n)/2 +1)/2,奇数: (m+n)/2+1
# ==>找出第(m+n)/2或(m+n)/2+1小的数 ==>找出第k小数

1).二分法 O(log(m+n)):

# 二分法:O(log(m+n))
"""
A[0,...,m],B[0,...,n]
C[0,...,k,...,m+n]
找C[k]即第k小数思路:
A[0,...,k//2-1,...,m]
B[0,...,k//2-1,...,n]
  | k//2  |
min(A[k//2-1],B[k//2-1])
	最少大于k//2-1个数,即[0,...,k//2-2];
	最多大于(k//2-1)*2 = k-2个数,即[0,...,k//2-2)]*2,若A[k//2-1]==B[k//2-1]也是最多大于k-2个数
	⇒ min(A[k//2-1],B[k//2-1])顶多是第k-1小数 ⇒ 不是第k个数且在k左边 ⇒ 那[0,k//2-2]肯定也在k左边
	⇒ [0,...,k//2-1]可以舍掉
	⇒ 找[k//2,...,m]           中第(k-((k//2-1) -0 +1))小的数
	     [0,...,k//2-1,...,n]
"""


class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        # 使用index_1 ,index_2实现对list的切割,因为只能从前面开始切。
        # newIndex_1/2 是要比较的数,小的话使index = newIndex+1 实现切割
        def findKmin(k):
            index_1, index_2 = 0, 0
            while 1:
                if index_1 == m:
                    return B[index_2 + k -1]
                if index_2 == n:
                    return A[index_1 + k -1]
                if k == 1:
                    return min(A[index_1], B[index_2])
                newIndex_1 = min(index_1+k//2-1,m-1)
                newIndex_2 = min(index_2+k//2-1,n-1)
                if A[newIndex_1]<=B[newIndex_2]:
                    k = k - (newIndex_1 - index_1 +1)
                    index_1 = newIndex_1 + 1
                else:
                    k = k - (newIndex_2 - index_2 +1)
                    index_2 = newIndex_2 + 1
        A,B = nums1, nums2
        m, n = len(A), len(B)
        totalLength = m + n
        if totalLength % 2 == 1:
            return findKmin(totalLength//2+1)
        else:
            return (findKmin(totalLength//2) + findKmin(totalLength//2+1))/2

2). 排序 O(nlog(k+n)):

#sort: O(nlog(k+n))
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums1.extend(nums2)#O(n)
        num = sorted(nums1)#O(nlog(m+n))
        #O(1)
        if len(num) % 2 == 1:
            return num[(len(num)-1)//2] 
        else:
            return (num[len(num)//2-1]+num[len(num)//2])/2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值