【LeetCode】4-寻找两个正序数组的中位数

欢迎来到李耶的频道【LeetCode面试题】。


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

题目

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

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

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

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

解法一:二分查找(分割线法)

思路:在较短的数组上用二分法确定分割线位置,使得左半部分最大值 ≤ 右半部分最小值,从而在 O(log(min(m,n))) 时间内求出中位数。

javascript 复制代码
function findMedianSortedArrays(nums1, nums2) {
  if (nums1.length > nums2.length) {
    [nums1, nums2] = [nums2, nums1];
  }

  const m = nums1.length;
  const n = nums2.length;
  let left = 0;
  let right = m;

  while (left <= right) {
    const i = Math.floor((left + right) / 2);
    const j = Math.floor((m + n + 1) / 2) - i;

    const nums1Left = i === 0 ? -Infinity : nums1[i - 1];
    const nums1Right = i === m ? Infinity : nums1[i];
    const nums2Left = j === 0 ? -Infinity : nums2[j - 1];
    const nums2Right = j === n ? Infinity : nums2[j];

    if (nums1Left <= nums2Right && nums2Left <= nums1Right) {
      if ((m + n) % 2 === 1) {
        return Math.max(nums1Left, nums2Left);
      }
      return (Math.max(nums1Left, nums2Left) + Math.min(nums1Right, nums2Right)) / 2;
    } else if (nums1Left > nums2Right) {
      right = i - 1;
    } else {
      left = i + 1;
    }
  }
}
  • 时间复杂度 / 空间复杂度:O(log(min(m,n))) / O(1)
  • 优势:完全满足题目 O(log(m+n)) 的要求,是面试中的最优解

解法二:双指针归并(暴力法)

思路:用双指针将两个数组合并成一个有序数组,然后直接取中位数。虽然直观易懂,但时间复杂度不满足题目要求。

javascript 复制代码
function findMedianSortedArrays(nums1, nums2) {
  const merged = [];
  let i = 0;
  let j = 0;

  while (i < nums1.length && j < nums2.length) {
    if (nums1[i] < nums2[j]) {
      merged.push(nums1[i++]);
    } else {
      merged.push(nums2[j++]);
    }
  }

  while (i < nums1.length) merged.push(nums1[i++]);
  while (j < nums2.length) merged.push(nums2[j++]);

  const mid = Math.floor(merged.length / 2);
  if (merged.length % 2 === 1) {
    return merged[mid];
  }
  return (merged[mid - 1] + merged[mid]) / 2;
}
  • 时间复杂度 / 空间复杂度:O(m+n) / O(m+n)
  • 优势:思路简单,适合快速验证逻辑,但不满足题目复杂度要求,面试中不推荐

解法对比

解法 时间 / 空间复杂度 满足 O(log(m+n)) 推荐指数
二分查找(分割线法) O(log(min(m,n))) / O(1) ⭐⭐⭐⭐⭐
双指针归并 O(m+n) / O(m+n) ⭐⭐

扩展题

  1. 数据流的中位数:设计一个支持以下两种操作的数据结构:添加一个整数,以及返回当前所有元素的中位数。
  2. 两个有序数组的第 K 小元素:给定两个有序数组,找出它们合并后的第 K 小的元素。
  3. 寻找两个正序数组的中位数(允许重复元素):如果数组中有重复元素,中位数的定义是否需要调整?

"天下难事,必作于易;天下大事,必作于细。" ------ 老子

关注李耶,每天一道面试题,一起卷起来 🔥

相关推荐
小O的算法实验室3 小时前
IEEE TASE,基于MPC的多无人机协同搜索竞争群体优化方法
算法
城管不管4 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
Tbisnic4 小时前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
Brilliantwxx5 小时前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法
空堂与归6 小时前
用户分群找不到规律?用K-Means聚类算法自动发现数据模式
算法·机器学习·kmeans·聚类
动词ing6 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习6 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
一只小小的芙厨7 小时前
基础数论总结
笔记·学习·算法
夜不会漫长8 小时前
C++入门(1)
开发语言·c++·算法
wen_zhufeng9 小时前
IndexTTS 2.5 技术报告
人工智能·算法·机器学习