LeetCode-4. 寻找两个正序数组的中位数【数组 二分查找 分治】

LeetCode-4. 寻找两个正序数组的中位数【数组 二分查找 分治】

题目描述:

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

算法的时间复杂度应该为 O(log (m+n)) 。

示例 1:

输入:nums1 = 1,3, nums2 = 2

输出:2.00000

解释:合并数组 = 1,2,3 ,中位数 2

示例 2:

输入:nums1 = 1,2, nums2 = 3,4

输出:2.50000

解释:合并数组 = 1,2,3,4 ,中位数 (2 + 3) / 2 = 2.5

提示:

nums1.length == m

nums2.length == n

0 <= m <= 1000

0 <= n <= 1000

1 <= m + n <= 2000

-106 <= nums1i, nums2i <= 106

解题思路一:二分查找 分治。

  1. 找第k小数
    对于两个有序数组,我们要找第k小的数
    由于时间复制度要求是log,所以自然的想法就是对两个数组每次切一半。
    好,假设我们取两个数组k/2位置上的数(这里暂时不考虑上溢)
    如果nums1k/2>=nums2k/2,这意味着:
    nums2数组的左半边都不需要考虑了,因为肯定会比第k小的数要来得小。
    所以我们可以切掉nums2数组的一半,如此递归,每次都能切走一半
    自然能达到O(log(m+n))复杂度的要求了。
    在具体的代码实现中,为了方便处理边界情况,
    我们可以令nums1始终是长的那个数组,
    然后令t = min(k//2,len(nums2))便可以防止上溢的发生。
python 复制代码
def helper(nums1,nums2,k):
    if(len(nums1) <len(nums2) ):
        nums1, nums2 = nums2 , nums1 #保持nums1比较长
    if(len(nums2)==0):
        return nums1[k-1] # 短数组空,直接返回
    if(k==1):
        return min(nums1[0],nums2[0])  #找最小数,比较数组首位
    t = min(k//2,len(nums2)) # 保证不上溢
    if( nums1[t-1]>=nums2[t-1] ):
        return helper(nums1 , nums2[t:],k-t)
    else:
        return helper(nums1[t:],nums2,k-t)
  1. 找中位数
    为了处理奇偶时候中位数不同的计算方法,
    这里可以采用一个小技巧:

令 k1 = ( len(nums1) + len(nums2) + 1 ) // 2

令 k2 = ( len(nums1) + len(nums2) + 2 ) // 2

对于偶数情况,k1对应中间左边,k2对应中间右边

对于奇数情况,k1,k2都对应中间

所以我们得到了获得中位数的统一方法:(helper(k1)+helper(k2))/2

缺点是:用了两倍的计算量;优点是:代码统一、清晰。

python 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        k1 = (len(nums1) + len(nums2) + 1) // 2
        k2 = (len(nums1) + len(nums2) + 2) // 2
        def helper(nums1, nums2, k): #本质上是找第k小的数
            if len(nums1) < len(nums2): #保持nums1比较长
                nums1, nums2 = nums2, nums1
            if len(nums2) == 0: # 短数组空,直接返回
                return nums1[k-1]
            if k == 1:
                return min(nums1[0], nums2[0]) #找最小数,比较数组首位
            t = min(k//2, len(nums2)) # 保证不上溢
            if nums1[t-1] >= nums2[t-1]:
                return helper(nums1, nums2[t:], k-t)
            else:
                return helper(nums1[t:], nums2, k-t)
        return (helper(nums1,nums2,k1) + helper(nums1, nums2, k2)) / 2

时间复杂度:O(log(n+m))

空间复杂度:O(1)

解题思路二:0

python 复制代码

时间复杂度:O(n)

空间复杂度:O(n)

解题思路三:0

python 复制代码

时间复杂度:O(n)

空间复杂度:O(n)

相关推荐
倒头就睡的小比特4 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark4 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集
码流子4 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven4 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark4 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218614 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法