LeetCode 题解工作台

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

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2 。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 示例 1: 输入: nums1 = [1,3], nums2 = [2] 输出: 2.00000 解释: 合并数组 …

category

3

题型

code_blocks

10

代码语言

hub

3

相关题

当前训练重点

困难 · 二分·搜索·答案·空间

bolt

答案摘要

题目要求算法的时间复杂度为 $O(\log (m + n))$,因此不能直接遍历两个数组,而是需要使用二分查找的方法。 如果 $m + n$ 是奇数,那么中位数就是第 $\left\lfloor\frac{m + n + 1}{2}\right\rfloor$ 个数;如果 $m + n$ 是偶数,那么中位数就是第 $\left\lfloor\frac{m + n + 1}{2}\right\rfl…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给定两个大小分别为 mn 的正序(从小到大)数组 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 <= nums1[i], nums2[i] <= 106
lightbulb

解题思路

方法一:分治

题目要求算法的时间复杂度为 O(log(m+n))O(\log (m + n)),因此不能直接遍历两个数组,而是需要使用二分查找的方法。

如果 m+nm + n 是奇数,那么中位数就是第 m+n+12\left\lfloor\frac{m + n + 1}{2}\right\rfloor 个数;如果 m+nm + n 是偶数,那么中位数就是第 m+n+12\left\lfloor\frac{m + n + 1}{2}\right\rfloor 和第 m+n+22\left\lfloor\frac{m + n + 2}{2}\right\rfloor 个数的平均数。实际上,我们可以统一为求第 m+n+12\left\lfloor\frac{m + n + 1}{2}\right\rfloor 个数和第 m+n+22\left\lfloor\frac{m + n + 2}{2}\right\rfloor 个数的平均数。

因此,我们可以设计一个函数 f(i,j,k)f(i, j, k),表示在数组 nums1nums1 的区间 [i,m)[i, m) 和数组 nums2nums2 的区间 [j,n)[j, n) 中,求第 kk 小的数。那么中位数就是 f(0,0,m+n+12)f(0, 0, \left\lfloor\frac{m + n + 1}{2}\right\rfloor)f(0,0,m+n+22)f(0, 0, \left\lfloor\frac{m + n + 2}{2}\right\rfloor) 的平均数。

函数 f(i,j,k)f(i, j, k) 的实现思路如下:

  • 如果 imi \geq m,说明数组 nums1nums1 的区间 [i,m)[i, m) 为空,因此直接返回 nums2[j+k1]nums2[j + k - 1]
  • 如果 jnj \geq n,说明数组 nums2nums2 的区间 [j,n)[j, n) 为空,因此直接返回 nums1[i+k1]nums1[i + k - 1]
  • 如果 k=1k = 1,说明要找第一个数,因此只需要返回 nums1[i]nums1[i]nums2[j]nums2[j] 中的最小值;
  • 否则,我们分别在两个数组中查找第 k2\left\lfloor\frac{k}{2}\right\rfloor 个数,设为 xxyy。(注意,如果某个数组不存在第 k2\left\lfloor\frac{k}{2}\right\rfloor 个数,那么我们将第 k2\left\lfloor\frac{k}{2}\right\rfloor 个数视为 ++\infty。)比较 xxyy 的大小:
    • 如果 xyx \leq y,则说明数组 nums1nums1 的第 k2\left\lfloor\frac{k}{2}\right\rfloor 个数不可能是第 kk 小的数,因此我们可以排除数组 nums1nums1 的区间 [i,i+k2)[i, i + \left\lfloor\frac{k}{2}\right\rfloor),递归调用 f(i+k2,j,kk2)f(i + \left\lfloor\frac{k}{2}\right\rfloor, j, k - \left\lfloor\frac{k}{2}\right\rfloor)
    • 如果 x>yx > y,则说明数组 nums2nums2 的第 k2\left\lfloor\frac{k}{2}\right\rfloor 个数不可能是第 kk 小的数,因此我们可以排除数组 nums2nums2 的区间 [j,j+k2)[j, j + \left\lfloor\frac{k}{2}\right\rfloor),递归调用 f(i,j+k2,kk2)f(i, j + \left\lfloor\frac{k}{2}\right\rfloor, k - \left\lfloor\frac{k}{2}\right\rfloor)

时间复杂度 O(log(m+n))O(\log(m + n)),空间复杂度 O(log(m+n))O(\log(m + n))。其中 mmnn 分别是数组 nums1nums1nums2nums2 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        def f(i: int, j: int, k: int) -> int:
            if i >= m:
                return nums2[j + k - 1]
            if j >= n:
                return nums1[i + k - 1]
            if k == 1:
                return min(nums1[i], nums2[j])
            p = k // 2
            x = nums1[i + p - 1] if i + p - 1 < m else inf
            y = nums2[j + p - 1] if j + p - 1 < n else inf
            return f(i + p, j, k - p) if x < y else f(i, j + p, k - p)

        m, n = len(nums1), len(nums2)
        a = f(0, 0, (m + n + 1) // 2)
        b = f(0, 0, (m + n + 2) // 2)
        return (a + b) / 2
speed

复杂度分析

指标
时间O(\log(\min(m, n)))
空间O(1)
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate demonstrates a clear understanding of binary search over a valid answer space.

  • question_mark

    The candidate can explain how the partitioning logic helps in avoiding unnecessary merging of arrays.

  • question_mark

    The candidate can handle edge cases, like odd or even total lengths, while maintaining time efficiency.

warning

常见陷阱

外企场景
  • error

    Confusing partitioning logic can lead to incorrect median calculations.

  • error

    Failing to account for edge cases where one array is empty or the partitioning is imbalanced.

  • error

    Over-complicating the solution by attempting to merge the arrays instead of using binary search.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Handling arrays with significantly different lengths (m << n or n << m).

  • arrow_right_alt

    Solving the problem with multiple edge cases like empty arrays.

  • arrow_right_alt

    Optimizing for very large input arrays (up to 2000 elements).

help

常见问题

外企场景

寻找两个正序数组的中位数题解:二分·搜索·答案·空间 | LeetCode #4 困难