当前位置: 首页 > news >正文

【Leetcode hot 100】4.寻找两个正序数组的中位数

问题链接

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

问题描述

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

算法的时间复杂度应该为 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
  • -10^6 <= nums1[i], nums2[i] <= 10^6

问题解答

核心思路是通过二分查找将问题转化为 “寻找两个有序数组中的第 k 小元素”,再利用中位数的定义(奇数取中间值,偶数取中间两值平均)得到结果。

方法原理

1. 中位数与第 k 小元素的关联

设两个数组长度分别为 mn,总长度为 total = m + n

  • total奇数:中位数是第 (total + 1) / 2 小的元素(如 total=3,取第 2 小)。
  • total偶数:中位数是第 total/2 小和第 (total/2)+1 小元素的平均值(如 total=4,取第 2、3 小的平均)。

为简化代码,统一计算第 left = (total + 1) / 2 小和第 right = (total + 2) / 2 小的元素,再求平均——奇数时 left = right,结果等价于直接取中间值。

2. 二分查找找第 k 小元素

通过二分法每次淘汰两个数组中“不可能包含第 k 小元素”的前 k/2 个元素,逐步缩小搜索范围:

  1. 边界处理:若某数组已遍历完(起始索引超出长度),直接从另一数组取第 k 小元素。
  2. k=1 特殊情况:直接返回两个数组当前起始位置的最小值(此时第 1 小即最小值)。
  3. 二分淘汰
    • 分别取两个数组当前起始位置后 k/2 - 1 索引的值(记为 mid1mid2),若数组长度不足则取 Integer.MAX_VALUE(表示该数组无足够元素可淘汰)。
    • mid1 < mid2:说明 nums1 的前 k/2 个元素不可能是第 k 小,淘汰它们(起始索引后移 k/2),并更新 k = k - k/2
    • 反之:淘汰 nums2 的前 k/2 个元素,同理更新 k
  4. 递归/迭代缩小范围:重复上述步骤,直到 k=1 或某数组遍历完。

完整 Java 代码

class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m = nums1.length;int n = nums2.length;int total = m + n;// 计算需要找的第 left 小和第 right 小元素int left = (total + 1) / 2;int right = (total + 2) / 2;// 两元素平均值即为中位数return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;}/*** 寻找两个有序数组中的第 k 小元素* @param nums1 第一个有序数组* @param i     nums1 的当前起始搜索索引* @param nums2 第二个有序数组* @param j     nums2 的当前起始搜索索引* @param k     目标第 k 小元素* @return 第 k 小元素的值*/private int findKth(int[] nums1, int i, int[] nums2, int j, int k) {// 边界1:nums1 已遍历完,直接从 nums2 取第 k 小(j + k - 1 索引)if (i >= nums1.length) {return nums2[j + k - 1];}// 边界2:nums2 已遍历完,直接从 nums1 取第 k 小if (j >= nums2.length) {return nums1[i + k - 1];}// 边界3:k=1,返回当前起始位置的最小值if (k == 1) {return Math.min(nums1[i], nums2[j]);}// 计算当前要比较的中间索引(避免越界,越界则设为最大值)int mid1 = (i + k/2 - 1 < nums1.length) ? nums1[i + k/2 - 1] : Integer.MAX_VALUE;int mid2 = (j + k/2 - 1 < nums2.length) ? nums2[j + k/2 - 1] : Integer.MAX_VALUE;// 二分淘汰:淘汰较小值所在数组的前 k/2 个元素if (mid1 < mid2) {// 淘汰 nums1 的前 k/2 个,更新起始索引和 kreturn findKth(nums1, i + k/2, nums2, j, k - k/2);} else {// 淘汰 nums2 的前 k/2 个,更新起始索引和 kreturn findKth(nums1, i, nums2, j + k/2, k - k/2);}}
}

代码解释

  1. 主函数 findMedianSortedArrays

    • 计算总长度 total,确定需要寻找的第 left 小和第 right 小元素。
    • 调用 findKth 方法获取这两个元素,返回它们的平均值(自动处理奇偶数情况)。
  2. 辅助函数 findKth

    • 边界处理:当某数组遍历完(i >= mj >= n),直接从另一数组取对应位置元素。
    • k=1 处理:直接返回两数组当前起始位置的最小值,避免无意义的二分。
    • 二分比较:通过 mid1mid2 确定淘汰哪部分元素,缩小 k 和搜索范围,递归直至找到目标元素。

复杂度分析

  • 时间复杂度:O(log(m+n))。每次二分操作将 k 缩小一半,总递归/迭代次数为 log(m+n)。
  • 空间复杂度:O(log(m+n))。递归调用栈的深度为 log(m+n)(若改为迭代实现,空间复杂度可优化至 O(1))。

测试用例验证

示例 1

  • 输入:nums1 = [1,3]nums2 = [2]
  • 总长度 total=3left=2right=2
  • findKth(nums1,0,nums2,0,2) 过程:
    1. k=2,mid1 = nums1[0] = 1,mid2 = nums2[0] = 2。
    2. mid1 < mid2,淘汰 nums1 前 1 个元素,k=1,起始索引 i=1。
    3. 此时 k=1,返回 min(nums1[1]=3, nums2[0]=2) = 2。
  • 结果:2.0,符合预期。

示例 2

  • 输入:nums1 = [1,2]nums2 = [3,4]
  • 总长度 total=4left=2right=3
  • findKth(...,2) 返回 2,findKth(...,3) 返回 3,平均值为 2.5,符合预期。
http://www.dtcms.com/a/478124.html

相关文章:

  • HTB 赛季9靶场 - Signed
  • 任务栏透明度调节工具
  • 网站企业电子商务网站建设教学计划
  • 淘宝一番赏抽赏小程序:开启趣味抽赏新体验
  • 上海专业网站建站扬州北京网站建设
  • HTTP初识(二)
  • 【10 分钟!M4 Mac mini 离线部署「私有 ChatGPT」完整实录】
  • 怎么给网站做动图网络营销中的四种方法
  • API测试 | 3步走,通过协作实现API的高质量交付
  • 消息鉴别码的种类
  • C++设计模式之行为型模式:策略模式(Strategy)
  • 接口安全测试实战:从数据库错误泄露看如何构建安全防线
  • h5游戏网站建设做网站被网警找
  • 微美全息(NASDAQ:WIMI)融合区块链+AI+IoT 三大技术,解锁物联网入侵检测新范式
  • Shiro_认证绕过漏洞复现:原理详解+环境搭建+渗透实践(CVE-2020-1957)
  • 三维实时渲染应用开发及场景设计
  • RK3588 + 银河麒麟部署 swarm 集群指南
  • 基于 PyTorch 实现 MNIST 手写数字识别
  • 网站建设找王科杰信誉wordpress企业产品列表
  • 深入 Spring 依赖注入底层原理
  • WebRTC技术如何实现音视频通话
  • 韩国免费行情网站的推荐理由门户网站建设工作会议
  • Python psycopg2 教程
  • 5CEBA2U15I7N 阿尔特拉 Altera Cyclone V FPGA
  • 辉县市工程建设网站建设网站做宣传的免费渠道有那种
  • 2025年10月13日总结
  • perl-Test-Simple-1.302195-5.fc39.noarch.rpm 怎么安装?Fedora 39 安装步骤讲解
  • 图像处理之浓度(AI 调研)
  • 问答网站建设怎么提问郑州网站建设网络推广
  • T:堆的基本介绍