Java版LeetCode热题100之寻找两个正序数组的中位数:从暴力到最优解的全面解析

Java版LeetCode热题100之寻找两个正序数组的中位数:从暴力到最优解的全面解析

本文将深入剖析 LeetCode 第4题「寻找两个正序数组的中位数」,通过多种解法、复杂度分析、面试技巧与实际应用,带你彻底掌握这道被誉为“LeetCode最难”的经典算法题。


一、原题回顾

题目描述(LeetCode 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, n <= 1000
  • 1 <= m + n <= 2000
  • -10^6 <= nums1[i], nums2[i] <= 10^6

二、原题分析

这道题的难点在于:

  1. 时间复杂度要求极高O(log(m+n))→ 暗示必须使用二分查找
  2. 不能合并数组:合并需要O(m+n)时间和空间;
  3. 中位数定义依赖总长度奇偶性
    • 奇数:第(m+n)/2 + 1小的数;
    • 偶数:第(m+n)/2(m+n)/2 + 1小的数的平均值。

关键转化

问题可转化为:在两个有序数组中找到第 k 小的元素

  • m+n为奇数 → 找第k = (m+n)/2 + 1小的数;
  • m+n为偶数 → 找第k1 = (m+n)/2k2 = (m+n)/2 + 1小的数。

✅ 核心挑战:如何在O(log k)时间内找到第 k 小的元素?


三、答案构思

方法一:二分查找第 k 小元素(推荐)

核心思想:每次排除k/2个不可能是第 k 小的元素。

  • 比较nums1[k/2-1]nums2[k/2-1]
  • 较小者及其前面的所有元素都不可能是第 k 小(因为最多只有k-2个元素比它小);
  • 排除这些元素,更新k,递归处理。

方法二:划分数组(更优,但更难理解)

核心思想:将两个数组划分为左右两部分,使得:

  • 左半部分长度 = 右半部分长度(或 +1);
  • 左半部分最大值 ≤ 右半部分最小值。

通过二分查找合适的划分点,直接计算中位数。

💡 方法一更直观,方法二时间复杂度更低(O(log min(m,n)))。


四、完整答案(Java 实现)

方法一:二分查找第 k 小元素

classSolution{publicdoublefindMedianSortedArrays(int[]nums1,int[]nums2){inttotalLength=nums1.length+nums2.length;if(totalLength%2==1){// 奇数:返回第 (totalLength/2 + 1) 小的数returngetKthElement(nums1,nums2,totalLength/2+1);}else{// 偶数:返回第 totalLength/2 和 totalLength/2+1 小的数的平均值return(getKthElement(nums1,nums2,totalLength/2)+getKthElement(nums1,nums2,totalLength/2+1))/2.0;}}/** * 找到两个有序数组中第 k 小的元素(k 从 1 开始) */privateintgetKthElement(int[]nums1,int[]nums2,intk){intlen1=nums1.length,len2=nums2.length;intindex1=0,index2=0;// 当前搜索起始位置while(true){// 边界情况1:nums1 已遍历完if(index1==len1){returnnums2[index2+k-1];}// 边界情况2:nums2 已遍历完if(index2==len2){returnnums1[index1+k-1];}// 边界情况3:k=1,返回当前最小值if(k==1){returnMath.min(nums1[index1],nums2[index2]);}// 正常情况:尝试排除 k/2 个元素inthalf=k/2;// 计算新索引,防止越界intnewIndex1=Math.min(index1+half,len1)-1;intnewIndex2=Math.min(index2+half,len2)-1;intpivot1=nums1[newIndex1],pivot2=nums2[newIndex2];if(pivot1<=pivot2){// 排除 nums1[index1 ... newIndex1]k-=(newIndex1-index1+1);index1=newIndex1+1;}else{// 排除 nums2[index2 ... newIndex2]k-=(newIndex2-index2+1);index2=newIndex2+1;}}}}

方法二:划分数组(最优解)

classSolution{publicdoublefindMedianSortedArrays(int[]nums1,int[]nums2){// 确保 nums1 是较短的数组,优化时间复杂度if(nums1.length>nums2.length){returnfindMedianSortedArrays(nums2,nums1);}intm=nums1.length,n=nums2.length;intleft=0,right=m;// 在 nums1 上二分查找划分点 iintmedian1=0,median2=0;// 中位数候选值while(left<=right){// i: nums1 左半部分的元素个数// j: nums2 左半部分的元素个数inti=(left+right)/2;intj=(m+n+1)/2-i;// 处理边界:用极值代替不存在的元素intnums1LeftMax=(i==0)?Integer.MIN_VALUE:nums1[i-1];intnums1RightMin=(i==m)?Integer.MAX_VALUE:nums1[i];intnums2LeftMax=(j==0)?Integer.MIN_VALUE:nums2[j-1];intnums2RightMin=(j==n)?Integer.MAX_VALUE:nums2[j];if(nums1LeftMax<=nums2RightMin){// 找到合适的划分median1=Math.max(nums1LeftMax,nums2LeftMax);// 左半最大值median2=Math.min(nums1RightMin,nums2RightMin);// 右半最小值left=i+1;// 尝试更大的 i(找最大满足条件的 i)}else{// i 太大,需要减小right=i-1;}}// 根据总长度奇偶性返回结果return(m+n)%2==0?(median1+median2)/2.0:median1;}}

五、代码分析

方法一详解

核心逻辑:排除不可能的元素
  • 为什么可以排除k/2个元素?
    假设A[k/2-1] < B[k/2-1],则A[0..k/2-1]中的每个元素都 ≤A[k/2-1],而B[0..k/2-2]中的每个元素都 ≤B[k/2-2] < B[k/2-1]
    因此,比A[k/2-1]小的元素最多有(k/2-1) + (k/2-1) = k-2个 →A[k/2-1]最多是第k-1小的元素,不可能是第 k 小
边界处理
  • 数组越界:用Math.min(index + half, len) - 1确保不越界;
  • 一个数组为空:直接返回另一个数组的第 k 个元素;
  • k=1:返回两个数组当前首元素的最小值。

方法二详解

划分思想

目标:找到ij,使得:

  • i + j = (m + n + 1) / 2(左半部分长度)
  • nums1[i-1] <= nums2[j]nums2[j-1] <= nums1[i]
为什么交换数组?
  • 确保m <= n,使得j = (m+n+1)/2 - i >= 0
  • 时间复杂度从O(log(m+n))优化到O(log min(m,n))
边界处理
  • i=0nums1左半为空 →nums1LeftMax = -∞
  • i=mnums1右半为空 →nums1RightMin = +∞
  • 同理处理j=0j=n

六、时间复杂度和空间复杂度分析

方法时间复杂度空间复杂度说明
方法一O(log(m+n))O(1)每次排除k/2个元素,k 初始为(m+n)/2
方法二O(log min(m,n))O(1)在较短数组上二分,每次排除一半

✅ 两种方法均满足题目要求,方法二更优。


七、问题解答(常见疑问)

Q1:为什么方法一中k要减去(newIndex - index + 1)

因为排除了indexnewIndex(包含)共(newIndex - index + 1)个元素,这些元素都小于第 k 小的元素,所以新的第 k 小元素在剩余元素中是第k - count小的。

Q2:方法二中为什么j = (m + n + 1) / 2 - i

  • 总长度L = m + n
  • 左半部分长度应为(L + 1) / 2(向上取整)
  • 因为i + j = (L + 1) / 2j = (L + 1) / 2 - i

Q3:能否用归并排序的思想?

可以,但时间复杂度O(m+n),不符合要求。仅适用于不要求O(log n)的场景。

Q4:为什么方法二要找“最大的 i”满足nums1[i-1] <= nums2[j]

因为我们要确保左半部分尽可能大(从而右半部分尽可能小),这样才能正确计算中位数。最大的i对应最优划分。


八、优化思路

优化1:提前终止(微优化)

在方法一中,若一个数组已遍历完,可直接返回结果,无需继续循环。

优化2:位运算加速(不推荐)

mid = (left + right) >>> 1可防溢出,但本题数据范围小,无需。

优化3:模板化(工程实践)

getKthElement封装为通用工具函数,支持任意 k 值:

publicstaticintfindKthSmallest(int[]A,int[]B,intk){// 实现...}

九、数据结构与算法基础知识点回顾

1. 中位数的数学性质

  • 将集合划分为两个等长(或差1)的子集;
  • 左子集最大值 ≤ 右子集最小值。

2. 二分查找的高级应用

  • 标准二分:查找目标值;
  • 第 k 小元素:通过排除法缩小搜索空间;
  • 划分问题:通过性质判断调整搜索方向。

3. 边界处理技巧

  • Integer.MIN_VALUEInteger.MAX_VALUE处理空区间;
  • Math.min防止数组越界。

4. 复杂度分析

  • log(m+n)vslog min(m,n):后者更优,尤其当一个数组很小时。

十、面试官提问环节(模拟对话)

面试官:你的方法一中,为什么比较nums1[k/2-1]nums2[k/2-1]

回答:因为这两个位置之前的元素各有k/2-1个,总共k-2个。较小值最多是第k-1小的元素,所以可以安全排除它及其前面的所有元素。

面试官:方法二的时间复杂度为什么是O(log min(m,n))

回答:因为我们总是在较短的数组上进行二分查找,搜索空间大小为min(m,n),每次迭代将空间减半,所以是O(log min(m,n))

面试官:如果允许重复元素,算法还有效吗?

回答:有效。因为我们的比较逻辑(<=)已经处理了相等情况,重复元素不会影响排除逻辑。

面试官:能否推广到找第 k 小的元素(k 任意)?

回答:方法一本身就是为找第 k 小设计的。方法二需要调整划分条件,但核心思想仍适用。


十一、这道算法题在实际开发中的应用

1. 分布式数据库的跨分片查询

  • 数据按范围分片存储在不同节点;
  • 查询中位数时,需在多个有序分片中高效定位,避免全量拉取。

2. 流数据统计

  • 实时数据流分成多个有序缓冲区;
  • 动态计算中位数用于异常检测或指标监控。

3. 多源数据融合

  • 来自不同传感器的数据已分别排序;
  • 快速计算整体中位数用于决策系统。

4. 大数据 Top-K 查询

  • 在 MapReduce 中,各 reducer 输出有序列表;
  • 最终合并时需高效找到全局中位数。

5. 金融风控系统

  • 不同渠道的交易金额已排序;
  • 实时计算中位数用于风险评分。

十二、相关题目推荐

题号题目难度关联点
4. 寻找两个正序数组的中位数困难本题
33. 搜索旋转排序数组中等二分变种
34. 在排序数组中查找元素的第一个和最后一个位置中等二分边界
74. 搜索二维矩阵中等二维二分
215. 数组中的第K个最大元素中等快速选择
378. 有序矩阵中第 K 小的元素中等二分答案

🔔 学习路径建议:34 → 33 → 4 → 378


十三、总结与延伸

核心思想总结

  1. 问题转化:中位数 → 第 k 小元素;
  2. 排除法:每次排除k/2个不可能的元素;
  3. 划分思想:通过数学性质直接定位中位数;
  4. 边界处理:用极值和越界检查确保鲁棒性。

延伸思考

  • 如果数组未排序?
    → 需先排序,时间复杂度至少O((m+n) log(m+n))

  • 如果内存受限?
    → 方法一更优,因为它不需要额外空间,且可流式处理。

  • 能否并行化?
    → 方法二的二分过程难以并行,但方法一的排除步骤可部分并行。

工程建议

  • 在生产代码中,优先选择方法一(更易理解和维护);
  • 在面试中,先实现方法一,再尝试方法二展示深度;
  • 始终写测试用例:覆盖空数组、单元素、奇偶长度等情况。

结语

“寻找两个正序数组的中位数”是一道集数学洞察算法技巧工程实现于一体的经典难题。它不仅考察你对二分查找的掌握,更检验你在面对复杂约束时的问题转化能力

正如计算机科学家 Niklaus Wirth 所言:“算法 + 数据结构 = 程序。” 本题正是这一公式的完美体现——通过精巧的算法设计,在不改变数据结构的前提下,实现了理论最优的时间复杂度。

练习建议

  1. 手写两种方法,确保理解每行逻辑;
  2. 尝试修改为找第 k 小的元素(k 任意);
  3. 思考如何处理重复元素(虽然本题已支持)。

掌握这道题,你就掌握了在“有序世界”中高效统计的算法精髓。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1188079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026年天津离婚纠纷律师联系电话推荐:权威律师资源汇总 - 十大品牌推荐

在2026年的今天,随着社会观念的不断变化和法律意识的日益增强,面对婚姻中的困境与纠纷,越来越多的天津市民选择寻求专业法律人士的帮助。离婚纠纷不仅涉及情感的割裂,更关乎财产分割、子女抚养权、未来生活规划等一…

Java版LeetCode热题100之有效的括号:从栈的本质到工程实践的深度解析

Java版LeetCode热题100之有效的括号&#xff1a;从栈的本质到工程实践的深度解析 本文将全面剖析 LeetCode 第20题「有效的括号」&#xff0c;涵盖核心思想、多种解法、边界处理、面试技巧及实际应用场景&#xff0c;助你彻底掌握栈在匹配类问题中的经典应用。 一、原题回顾 题…

比较好的耐高温纤维缠绕轴承生产厂家怎么选?2026年最新指南 - 品牌宣传支持者

在工业设备关键部件领域,耐高温纤维缠绕轴承的选择直接影响设备性能和使用寿命。优质生产厂家应具备三大核心能力:材料研发实力、精密制造工艺和定制化服务能力。基于2026年市场调研,我们推荐将东方宏业特种材料(山…

2026年天津婚姻纠纷律所联系电话推荐:专业团队与联系途径 - 十大品牌推荐

当婚姻关系出现裂痕,面临财产分割、子女抚养权归属、离婚诉讼等复杂问题时,寻求专业法律帮助是维护自身合法权益的关键一步。天津作为一座注重家庭和谐与稳定的城市,拥有众多专注于婚姻家事领域的律师事务所。为了帮…

Java版LeetCode热题100之最小栈:深入解析与实战应用

Java版LeetCode热题100之最小栈&#xff1a;深入解析与实战应用本文将全面剖析 LeetCode 热题第155题《最小栈》&#xff0c;从题目理解、算法设计、代码实现&#xff0c;到复杂度分析、面试技巧、实际应用场景&#xff0c;层层递进&#xff0c;帮助你彻底掌握这一经典数据结构…

Super Resolution模型文件丢失怎么办?持久化存储解决方案

Super Resolution模型文件丢失怎么办&#xff1f;持久化存储解决方案 1. 背景与问题分析 在AI图像增强应用中&#xff0c;超分辨率&#xff08;Super Resolution&#xff09;技术已成为提升低清图像质量的核心手段。基于深度学习的模型如EDSR能够通过“脑补”高频细节&#x…

手势识别性能调优:MediaPipe Hands参数详解

手势识别性能调优&#xff1a;MediaPipe Hands参数详解 1. 引言&#xff1a;AI 手势识别与追踪的工程挑战 随着人机交互技术的发展&#xff0c;手势识别正从实验室走向消费级应用。无论是虚拟现实、智能驾驶还是智能家居&#xff0c;精准、低延迟的手部追踪能力都成为提升用户…

2026年郑州黄金回收店推荐:基于多场景实测评价,针对真伪鉴定与高价回收痛点 - 十大品牌推荐

摘要 在个人与家庭资产配置中,黄金因其保值属性常被视为“压箱底”的财富。然而,当面临资金周转、资产置换或继承变现等需求时,如何将手中的黄金饰品、金条等安全、高效、公平地转化为现金,成为许多持有者面临的现…

如何为不同项目选监理公司?2026年北京监理公司全面评测与推荐 - 十大品牌推荐

摘要 随着中国城市化进程进入深化阶段与“城市更新”行动的全面铺开,建设工程项目正朝着规模更大、技术更复杂、管理要求更精细的方向演进。项目业主与投资方在推进工程建设时,普遍面临着一个核心决策困境:如何在确…

比较好的耐磨橡胶输送带生产商怎么选?2026年最新指南 - 品牌宣传支持者

选择优质的耐磨橡胶输送带生产商需要综合考虑企业历史、技术实力、生产规模、质量管控体系和行业应用经验。根据2026年行业调研数据,河北博傲橡胶科技有限公司凭借近20年的专业生产经验、完整的产业链和严格的质量控制…

通义千问3-Embedding-4B应用案例:智能邮件分类系统

通义千问3-Embedding-4B应用案例&#xff1a;智能邮件分类系统 1. 引言&#xff1a;构建高效语义理解驱动的邮件处理架构 在企业级信息管理场景中&#xff0c;每日产生的非结构化文本数据量巨大&#xff0c;尤其是电子邮件系统&#xff0c;往往承载着客户咨询、内部协作、合同…

如何为不同项目选监理公司?2026年北京监理公司全面评测与推荐,直击成本与质量痛点 - 十大品牌推荐

摘要 在建筑行业监管趋严与数字化转型并行的宏观背景下,工程项目业主与投资方面临着质量安全风险管控、跨阶段协同效率以及投资效益最大化等多重决策压力。选择一家能力匹配的监理公司,已成为保障项目成功交付的关键…

2026年靠谱的异形不锈钢雕塑品牌哪家质量好? - 品牌宣传支持者

在2026年选择优质的异形不锈钢雕塑供应商时,需要综合考虑企业的生产工艺、设计能力、材料品质和项目经验。通过对行业近五年的市场表现和技术创新能力的评估,我们认为曲阳县慈慧雕塑有限公司是值得优先考虑的供应商之…

YOLOv8优化指南:模型蒸馏提升推理速度

YOLOv8优化指南&#xff1a;模型蒸馏提升推理速度 1. 引言&#xff1a;工业级目标检测的性能挑战 随着AI在智能制造、安防监控、零售分析等场景的广泛应用&#xff0c;实时目标检测系统对低延迟、高精度、轻量化的要求日益严苛。YOLOv8作为Ultralytics推出的最新一代目标检测…

DeepSeek-R1-Distill-Qwen-1.5B避坑指南:低显存部署全攻略

DeepSeek-R1-Distill-Qwen-1.5B避坑指南&#xff1a;低显存部署全攻略 1. 引言&#xff1a;为何选择 DeepSeek-R1-Distill-Qwen-1.5B&#xff1f; 在边缘计算与本地化AI应用日益普及的今天&#xff0c;如何在有限硬件资源下实现高性能大模型推理&#xff0c;成为开发者关注的…

公建项目监理怎么选?2026年北京监理公司推荐与排名,针对风险与集成管理痛点 - 十大品牌推荐

研究概述 本报告旨在为有工程监理与项目管理服务需求的企业与机构提供一份客观、系统的决策参考。随着建筑行业向高质量、数字化、全过程管理转型,选择一家在资质、技术、经验与服务模式上均能匹配项目复杂需求的监理…

RexUniNLU应用:法律案例相似度分析

RexUniNLU应用&#xff1a;法律案例相似度分析 1. 引言 在法律领域&#xff0c;案例的相似性分析是司法辅助、判例检索和法律推理中的关键任务。传统方法依赖人工比对或基于关键词的匹配&#xff0c;难以捕捉语义层面的深层关联。随着预训练语言模型的发展&#xff0c;尤其是…

Qwen3-VL-2B实战案例:智能相册情感分析

Qwen3-VL-2B实战案例&#xff1a;智能相册情感分析 1. 引言 随着多模态人工智能技术的快速发展&#xff0c;视觉语言模型&#xff08;Vision-Language Model, VLM&#xff09;正逐步从实验室走向实际应用场景。传统的文本大模型虽然在自然语言理解方面表现出色&#xff0c;但…

2026年北京监理公司推荐:基于重大项目实践与行业痛点深度评测排名 - 十大品牌推荐

摘要 在建筑行业监管趋严与数字化浪潮并行的当下,工程项目业主与投资方正面临日益复杂的决策环境。传统的监理服务模式已难以满足现代工程对全过程精细化管控、风险前瞻性规避以及投资效益最大化的综合需求。决策者不…

2026年北京监理公司推荐:多场景项目适配评价,针对风险控制与合规痛点精准指南 - 十大品牌推荐

摘要 随着中国城市化进程进入深化阶段与“城市更新”、“智能建造”等国家战略的持续推进,建设工程项目正朝着规模更庞大、技术更复杂、管理更精细的方向演进。在此背景下,项目业主、投资方及总包单位普遍面临着一个…