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

Problem: 4. 寻找两个正序数组的中位数

文章目录

思路

  1. 思路一:可以合并两个数组,然后排序,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度 O ( 1 ) O(1) O(1)
  2. 思路二:利用归并思想,合并两个数组,并按照合并后的数组的长度的奇偶返回中位数,时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n) 需要一个辅助数组
  3. 思路三(看的参考答案):二分

中位数把大的数组均分为两份,记合并后的有序数组nums长度为n:

  • 如果n为奇数,那么中位数就是nums[n//2],此时nums的两边的元素个数为(n+1)//2(包含中位数)
  • 如果n为偶数,那么中位数就是(nums[n//2] + nums[n//2+1]) / 2,此时nums的两边的元素个数为n//2
  • 由于是地板除,所以单侧元素的个数可以写为(n+1)//2,记为k

当确定nums1中的元素为m1时候,那么nums2中的元素只需要确定k-m1个,就可以找到中位数。

此时问题变为了,如何从nums1中寻找m1的位置=》【二分查找】

令指针l、r分别指向nums1的起始和nums的末尾

m1=l+r>>1

m2=k-m1

  • 当nums1[m1] < nums2[m2-1]时:nums1中有m1个元素(nums[0]...nums[m1-1])比nums[m1]小,nums2中最多有m2-1个元素比nums[m1]小,共计m1+m2-1=k-1,所以m1不可能是第k个元素,需要往右移动,l=m1+1
  • 当nums1[m1] >= nums[m2-1]时,需要往左移动,r=m1

最终就可以得到nums1的个数m1=l

nums2的个数为m2=k-c1

接下来就是判断长度为奇偶和处理边界

  • 当长度为奇数的时候可以直接返回奇数位置
  • 偶数时候,需要返回中间两个元素的均值
    需要注意,可能m1和m2可能会越界
    具体而言,当寻找左侧元素c1的时候,m1和m2可能会<=0(数组递增,所以此时标记为-inf),此时需要特判
    当寻找右侧元素(偶数)时候,m1和m2可能会超过各自数组的长度(数组递增,所以此时标记为inf),此时也需要特判

解题方法

二分查找

复杂度

时间复杂度: O ( l o g 2 ( m + n ) ) O(log_2(m+n)) O(log2(m+n)) 二分

空间复杂度: O ( 1 ) O(1) O(1) 若干常数中间变量

Code

Python3 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        n1 = len(nums1)
        n2 = len(nums2)
        if n1 > n2: return self.findMedianSortedArrays(nums2, nums1)

        l, r = 0, n1
        k = (n1 + n2 + 1) // 2
        while l < r:
            m1 = l + r >> 1
            m2 = k - m1
            if nums1[m1] < nums2[m2-1]:
                l = m1 + 1
            else:
                r = m1
        m1 = l
        m2 = k - m1
        c1 = max(float('-inf') if m1 <= 0 else nums1[m1 - 1], float('-inf') if m2 <= 0 else nums2[m2 - 1])
        if (n1 + n2) % 2 == 1:
            return c1
        c2 = min(float('inf') if m1 >= n1 else nums1[m1], float('inf') if m2 >= n2 else nums2[m2])

        return (c1 + c2) / 2
相关推荐
前端小刘哥30 分钟前
赋能在线教育与企业培训:视频直播点播平台EasyDSS视频点播的核心技术与应用实践
算法
吗~喽36 分钟前
【LeetCode】四数之和
算法·leetcode·职场和发展
Net_Walke1 小时前
【散列函数】哈希函数简介
算法·哈希算法
卿言卿语1 小时前
CC1-二叉树的最小深度
java·数据结构·算法·leetcode·职场和发展
码流之上1 小时前
【一看就会一写就废 指间算法】执行操作后的最大 MEX —— 同余、哈希表
算法·面试
仰泳的熊猫1 小时前
LeetCode:889. 根据前序和后序遍历构造二叉树
数据结构·c++·算法
2025年一定要上岸2 小时前
【日常学习】10-15 学习re
学习·算法·正则表达式
aramae2 小时前
数据结构与算法(递归)
开发语言·经验分享·笔记·算法
小欣加油2 小时前
leetcode 329 矩阵中的最长递增路径
c++·算法·leetcode·矩阵·深度优先·剪枝
Emilia486.2 小时前
【Leetcode&nowcode&数据结构】单链表的应用(初阶)
c语言·数据结构·算法·leetcode