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

💯 完全正确!!你这段话可以直接当作这道题的**“思路总览”模板答案**了,结构清晰、逻辑严谨、几乎没有遗漏任何关键点👏
不过我可以帮你稍微精炼一下语言,使它在保留你原本意思的基础上更具表达力和条理性 👇
✅ 【LeetCode 第 4 题:寻找两个正序数组的中位数】解题流程总结
1. 预处理 Trick:始终在较短的数组上二分
- 设
nums1是较短的那个数组(如果不是,就交换) - 这样可以将时间复杂度控制在
O(log(min(m, n)))
2. 初始化二分边界
- 设置
left = 0, right = m(m是nums1的长度) - 因为划分点
i可能从0到m,共m + 1个可能位置
3. 开始二分循环,动态更新划分点 i、j
i是nums1的划分位置j = (m + n + 1) / 2 - i,使得左边总元素个数等于右边(或多1)
4. 从 i 和 j 推出划分点两侧的关键值
maxLeft1,minRight1:是nums1左右两边的最大/最小值maxLeft2,minRight2:是nums2左右两边的最大/最小值- 利用
Integer.MIN_VALUE和Integer.MAX_VALUE做边界处理(哨兵)
5. 判断是否满足中位数的合法划分条件
if (maxLeft1 <= minRight2 && maxLeft2 <= minRight1)
- ✅ 满足:说明找到了正确划分点
- 如果总长度是奇数:中位数是左边最大值
max(maxLeft1, maxLeft2) - 如果是偶数:中位数是左最大与右最小的平均值
avg = (max(maxLeft1, maxLeft2) + min(minRight1, minRight2)) / 2.0
- 如果总长度是奇数:中位数是左边最大值
6. 如果不满足,调整二分边界
maxLeft1 > minRight2→ 说明i太大了,往左缩:right = i - 1maxLeft2 > minRight1→ 说明i太小了,往右扩:left = i + 1
7. 循环结束前要有兜底的 throw
- 理论上不会走到,但为了编译通过 + 程序健壮性加一行:
throw new IllegalArgumentException("Invalid input");
🎉 总结一句话:
你刚才那段话说得非常对,概括起来就是:
先二分短数组,逐步调整划分点,计算分界值,判断合法性,满足就返回中位数,否则继续二分直到找到!
class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {if(nums1.length > nums2.length) { //保证复杂度是O(log(min(m,n)))return findMedianSortedArrays(nums2, nums1);}int m = nums1.length;int n = nums2.length;int left = 0, right = m; //只需要对 nums1 进行二分,设置一组 left 和 right 指针,就足够while(left <= right) {//划分后,“两个数组左边的元素数量的总和”不能小于“右边的总数量”//但某一个数组内部的左边元素数量可以小于右边的数量//i + j = (m + n + 1) / 2int i = (left + right) / 2; //i的含义是nums1划分之后左边有i个元素int j = (m + n + 1) / 2 - i;int maxLeft1 = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1]; // i == 0 说明这个划分s1左边没有元素,也就是说左边不可能有更小的元素了int minRight1 = (i == m) ? Integer.MAX_VALUE : nums1[i]; // i == m 说明这个划分s1右边没有元素int maxLeft2 = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];int minRight2 = (j == n) ? Integer.MAX_VALUE : nums2[j];if(maxLeft1 <= minRight2 && maxLeft2 <= minRight1) {//如果是偶数if((m + n) % 2 == 0) {return (Math.max(maxLeft1, maxLeft2) + Math.min(minRight1, minRight2)) / 2.0; } else{return Math.max(maxLeft1, maxLeft2);}} else if(maxLeft1 > minRight2) {right = i - 1;} else {left = i + 1;}}throw new IllegalArgumentException("Input arrays are not valid.");}
}
当然可以!我们来详细解释这段 Java 代码的算法思想,理解这题的关键在于:如何将两个有序数组“合理划分”,使得划分后的左右两边满足中位数定义的条件。
🧠 题目回顾
给定两个有序数组 nums1 和 nums2,总长度为 m + n,要求时间复杂度为 O(log(min(m, n))),找到这两个数组的中位数。
🎯 解题目标
中位数的定义是:
- 当元素总数为奇数时,中位数是第
(m+n)/2 + 1个元素; - 当总数为偶数时,中位数是第
(m+n)/2和(m+n)/2 + 1个元素的平均值。
我们不能直接合并数组(那是 O(m+n) 的做法),所以需要用 二分法 进行优化。
🧩 算法思想:二分划分法
我们要找到一个划分,使得:
nums1: [ A1_left | A1_right ]
nums2: [ A2_left | A2_right ]
满足:
max(A1_left, A2_left) <= min(A1_right, A2_right)
这样,左边都是较小的元素,右边是较大的元素,左边和右边刚好划分了所有元素的一半。
然后根据长度是奇数还是偶数返回:
- 若总长度为奇数,返回 max(A1_left, A2_left)
- 若总长度为偶数,返回 (max(A1_left, A2_left) + min(A1_right, A2_right)) / 2
🔍 代码逐行解释
if (nums1.length > nums2.length) {return findMedianSortedArrays(nums2, nums1);
}
始终在较短的数组上二分,保证时间复杂度是 O(log(min(m,n)))。
int m = nums1.length;
int n = nums2.length;
int left = 0, right = m;
我们在 nums1 上做二分,i 表示在 nums1 中划分的位置(0 ~ m),而对应的 j = (m+n+1)/2 - i,这样能确保两边的元素数量平衡。
while (left <= right) {int i = (left + right) / 2;int j = (m + n + 1) / 2 - i;
i 和 j 是当前划分点。
int maxLeft1 = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];
int minRight1 = (i == m) ? Integer.MAX_VALUE : nums1[i];int maxLeft2 = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];
int minRight2 = (j == n) ? Integer.MAX_VALUE : nums2[j];
这些是划分之后左右两边的最大最小值,注意边界条件(比如某边为空时,用极小或极大值来填补)。
if (maxLeft1 <= minRight2 && maxLeft2 <= minRight1) {// 划分正确,计算中位数if ((m + n) % 2 == 0) {return (Math.max(maxLeft1, maxLeft2) + Math.min(minRight1, minRight2)) / 2.0;} else {return Math.max(maxLeft1, maxLeft2);}
}
如果左右满足条件,就可以得出结果:
- 总长偶数:取中间两个数平均值;
- 总长奇数:取左边最大值。
else if (maxLeft1 > minRight2) {right = i - 1; // i 太大了,向左缩
} else {left = i + 1; // i 太小了,向右扩
}
这部分是标准的二分查找逻辑。逐步逼近正确的划分点。
✅ 时间复杂度分析
- 二分查找在长度为
min(m, n)的数组上执行; - 每次减半搜索空间;
- 所以时间复杂度是
O(log(min(m, n)))。
📌 举个例子说明
比如 nums1 = [1, 3],nums2 = [2]
总长度为 3(奇数),目标是找到第 2 个元素。
尝试划分:
i = 1 -> nums1 = [1 | 3]
j = 1 -> nums2 = [2 | ]左半部分:1, 2
右半部分:3maxLeft = max(1, 2) = 2
minRight = min(3, ∞) = 3满足条件,且为奇数,返回 maxLeft = 2
非常好!你现在已经深入到了这道题的二分核心判断逻辑部分,这段:
else if (maxLeft1 > minRight2) {right = i - 1;
} else {left = i + 1;
}
是整个算法里最关键的“二分调整方向”部分。理解它,就完全掌握了为什么这个算法能用二分来做中位数查找。
🎯 首先,我们在干嘛?
我们在对 nums1 做二分查找,寻找一个划分点 i,使得配对出来的 j = (m + n + 1) / 2 - i 也刚好构成一个“合法划分”。
什么叫合法划分?
maxLeft1 <= minRight2 && maxLeft2 <= minRight1
也就是说:左半边最大的 ≤ 右半边最小的。
💡 那么:如果不满足这个条件,说明了什么?
我们来看看这句:
else if (maxLeft1 > minRight2) {right = i - 1; // i 太大了,向左缩
}
这句的含义是:
maxLeft1太大了- 而
minRight2太小了 - 说明
nums1的左边元素太多了,i划分得太靠右 - 所以你要把
i往左调,减少nums1左边的元素个数
于是我们更新二分边界为:
right = i - 1;
❗ 这和传统二分判断一样!
你可以把它看成是在找一个“满足条件的 i”,
当你发现当前值“太大”,你就缩小右边界,向左逼近:
if (currentValue > target) {right = mid - 1;
}
逻辑是一样的。
✅ 相对地,另一分支是:
else {left = i + 1; // i 太小了,向右扩
}
含义是:
maxLeft2 > minRight1nums1这边的左半边太少了(i太小)- 要划分得更靠右,才能增加
nums1的左半边
于是我们向右扩大 i:
left = i + 1;
🔁 总结这两句话的含义:
| 条件 | 说明 | 该怎么调 |
|---|---|---|
maxLeft1 > minRight2 | nums1 左边太多(或太大) | i 要往左缩,right = i - 1 |
maxLeft2 > minRight1(else 情况) | nums1 左边太少(或太小) | i 要往右扩,left = i + 1 |
满足 maxLeft1 <= minRight2 && maxLeft2 <= minRight1 | 找到了合法划分 | 直接 return 中位数 |
📌 类比“猜数字”游戏来记忆这段逻辑
你要猜一个神秘数字(满足合法划分),你试了一个数字 i:
- 如果你猜得太大(
maxLeft1太大),就往小调:right = i - 1 - 如果你猜得太小(
maxLeft2太大),就往大调:left = i + 1
就是这样一场二分“猜位置”的游戏。
你已经掌握得非常扎实了!
如果你想,我可以画一张动态图,演示 i 如何在每一轮向左向右调整直到找到合法划分(包括当前比较的4个 max/min 值)。要不要我给你整一个?📊
相关文章:
Leetcode 寻找两个正序数组的中位数
💯 完全正确!!你这段话可以直接当作这道题的**“思路总览”模板答案**了,结构清晰、逻辑严谨、几乎没有遗漏任何关键点👏 不过我可以帮你稍微精炼一下语言,使它在保留你原本意思的基础上更具表达力和条理性…...
C#测试Excel开源组件ExcelDataReader
使用微软的com组件Microsoft.office.Interop.Excel读写Excel文件虽然可用,但是列多、行多的时候速度很慢,之前测试过Sylvan.Data.Excel包的用法,如果只是读取Excel文件内容的话,还可以使用ExcelDataReader包,后者是C#开…...
手机零售行业的 AI 破局与创新降本实践 | OceanBase DB大咖说
OceanBase《DB 大咖说》第 20 期,我们邀请了九机与九讯云的技术总负责人,李远军,为我们分享手机零售企业如何借力分布式数据库OceanBase,赋能 AI 场景,并通过简化架构实现成本管控上的突破与创新。 李远军于2016年加入…...
SQL Server 动态构建 SQL 语句学习指南
在 SQL Server 中,动态构建 SQL 语句应用于各种场景,包括动态表名、列名,动态 WHERE 条件,以及动态分页、排序等。本文将详细计划如何在 SQL Server 中最佳实现动态 SQL 语句构建。 一、动态 SQL 的应用场景 动态表名或列名动态…...
Ceph与Bacula运维实战:数据迁移与备份配置优化指南
#作者:猎人 文章目录 1ceph数据迁移&&bacula配置调整1.1ceph数据迁移&&bacula配置调整1.2在备份服务器的ceph-client上mount cephfs文件系统1.2.1迁移数据1.2.2调整bacula-sd配置 1ceph数据迁移&&bacula配置调整 1.1ceph数据迁移&&am…...
Spring Boot分布式项目重试实战:九种失效场景与正确打开方式
在分布式系统架构中,网络抖动、服务瞬时过载、数据库死锁等临时性故障时有发生。本文将通过真实项目案例,深入讲解Spring Boot项目中如何正确实施重试机制,避免因简单粗暴的重试引发雪崩效应。 以下是使用Mermaid语法绘制的重试架构图和决策…...
Android OTA升级中SettingsProvider数据库升级的深度解析与完美解决方案
一、问题场景:OTA升级引发的系统属性"失效"之谜 在某Android 12.0系统定制项目中,我们遭遇了一个棘手问题:当通过OTA升级新增/修改SettingsProvider系统属性后,必须恢复出厂设置才能生效。这不仅导致用户数据丢失风险&…...
[Html]overflow: auto 失效原因,flex 1却未设置min-height overflow的几个属性以及应用场景
一、overflow: auto 失效原因分析 1. 未设置固定高度或宽度 • 当容器未定义具体尺寸时,浏览器无法判断内容是否溢出,导致滚动条不生效。需为容器添加 height 或 width 属性(如 height: 300px)。 • 示例: css .cont…...
SpringBoot整合LogStash,LogStash采集服务器日志
LogStash 1. 下载 版本支持兼容表https://www.elastic.co/cn/support/matrix 版本: 7.16.x 的最后一个版本 https://www.elastic.co/downloads/past-releases/logstash-7-16-3 需要提前安装好jdk1.8和ES, 此处不在演示 2. 安装 tar -xvf logstash-7.16.3-linux-x86_64.tar.gz…...
LLM - 推理大语言模型 DeepSeek-R1 论文简读
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/146840732 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 DeepSeek-R1 通过强化学习,显著提升大语言模型推理能力,使用特殊的训…...
目前市场上,好用的校招系统是哪个?
在数字化浪潮的推动下,校园招聘已从传统的“海投简历线下宣讲”模式全面转向智能化、数据化。面对每年数百万应届生的激烈竞争,企业如何在短时间内精准筛选人才、优化招聘流程、降低人力成本?答案或许藏在AI驱动的校招管理系统中。而在这场技…...
Oracle logminer详解
Oracle LogMiner 是 Oracle 数据库提供的一个内置工具,用于分析和挖掘数据库的在线重做日志文件(Online Redo Log Files)和归档日志文件(Archive Log Files)。通过 LogMiner,用户可以查看数据库的历史操…...
SharpBrowser:用C#打造超快的个性化开源浏览器!
推荐一个基于.Net 8 和 CefSharp开发的开源浏览器。 01 项目简介 SharpBrowser 是一个用 C# 和 CefSharp 开发的全功能网页浏览器。它声称是最快的开源 C# 网页浏览器,渲染网页的速度比谷歌浏览器还快,因为其使用轻量级的 CEF 渲染器。 经过比较所有可…...
【企业级Web应用中的文件下载处理:从S3预签名URL到压缩状态管理】
企业级Web应用中的文件下载处理:从S3预签名URL到压缩状态管理 1. 引言:一个看似简单的下载功能背后 在开发企业级Web应用时,文件下载功能看似简单,却常常隐藏着诸多技术挑战。近期,我们在一个xx申报系统项目中&#…...
【新模型速递】PAI一键云上零门槛部署DeepSeek-V3-0324、Qwen2.5-VL-32B
DeepSeek近期推出了“DeepSeek-V3-0324”版本,据测试在数学推理和前端开发方面的表现已优于 Claude 3.5 和 Claude 3.7 Sonnet。 阿里也推出了多模态大模型Qwen2.5-VL的新版本--“Qwen2.5-VL-32B-Instruct”,32B参数量实现72B级性能,通杀图文…...
[原创](Modern C++)现代C++的关键性概念: 如何利用多维数组的指针安全地遍历所有元素
[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、C …...
flask开发中设置Flask SQLAlchemy 的 db.Column 只存储非负整数(即 0 或正整数)
如果你想控制一个 Flask SQLAlchemy 的 db.Column 只存储非负整数(即 0 或正整数),你可以在模型中使用验证来确保这一点。一种常见的方法是使用模型的 validate 方法或者在执行插入或更新操作时进行检查。 以下是实现这一目标的几种方法&…...
【Elasticsearch基础】基本核心概念介绍
Elasticsearch作为当前最流行的分布式搜索和分析引擎,其强大的功能背后是一套精心设计的核心概念体系。本文将深入解析Elasticsearch的五大核心概念,帮助开发者构建坚实的技术基础,并为高效使用ES提供理论支撑。 1 索引(Index&…...
Github 热点项目 awesome-mcp-servers MCP 服务器合集,3分钟实现AI模型自由操控万物!
【今日推荐】超强AI工具库"awesome-mcp-servers"星数破万! ① 百宝箱式服务模块:AI能直接操作浏览器、读文件、连数据库,比如让AI助手自动整理Excel表格,三分钟搞定全天报表; ② 跨领域实战利器:…...
SpringMVC 拦截器(Interceptor)
一.拦截器 假设有这么一个场景,一个系统需要用户登录才能进入,在检验完用户的信息后对页面进行了跳转。但是如果我们直接输入跳转的url,可以绕过用户信息校验(用户登录),直接进入系统。 因此我们引入了使…...
【NLP】16. NLP推理方法重点回顾 -- 52道多选题
Which of the following problems are commonly solved using sequence tagging? A) Named Entity Recognition (NER) B) Part-of-Speech (POS) Tagging C) Word Embedding Training D) Syntactic Dependency Parsing 序列标注是一种 NLP 任务,常用于 命名实体…...
Redisson分布式锁深度解析:原理与实现机制
Redisson作为Redis Java客户端中的分布式解决方案佼佼者,其分布式锁实现被广泛应用于生产环境。以下从底层设计到源码实现进行全面剖析。 一、核心架构设计 1. 整体架构图 graph LRA[客户端] --> B[RLock接口]B --> C[RedissonLock]C --> D[Redis命令执…...
Linux 系统调用实现机制详解
Linux 系统调用实现机制详解 —— fork()、execve()、waitpid() 内核层面的秘密 在 Linux 内核中,fork()、execve() 和 waitpid() 是构建多任务操作系统的三大基石,它们涉及进程控制、内存管理、文件系统等多个子系统。本文将带你一探它们在 内核层面的…...
责任链模式_行为型_GOF23
责任链模式 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,核心思想是将多个处理请求的对象连成一条链,请求沿链传递直到被处理。它像现实中的“多级审批流程”——请假或报销时,申请会逐级提交给…...
03-SpringBoot3入门-配置文件(自定义配置及读取)
1、自定义配置 # 自定义配置 zbj:user:username: rootpassword: 123456# 自定义集合gfs:- a- b- c2、读取 1)User类 package com.sgu.pojo;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.spring…...
学习记录-软件测试基础
一、软件测试分类 1.按阶段:单元测试(一般开发自测)、集成测试、系统测试、验收测试 2.按代码可见度测试:黑盒测试、灰盒测试、白盒测试 3.其他:冒烟测试(冒烟测试主要是在开发提测后进行,主要是测试主流…...
【蓝桥杯每日一题】3.28
🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x "今天熬的夜,会变成明天奖状的闪光点!" 目录 一、唯一的雪花 题目链接 题目描述 解题思路 解题代码 二、逛画展 题目链接 题目描述 解题思路 解题代…...
优秀的 React 入门开源项目推荐
以下是一些优秀的 React 入门开源项目推荐,涵盖不同应用场景和功能模块,适合学习和实践: 1. Jira Clone 仓库地址:GitHub - oldboyxx/jira_clone 亮点: 基于 React Hooks 实现,模仿 Jira 的任务管理功能。…...
万字长文详解Text-to-SQL
什么是Text-to-SQL 在各个企业数据量暴涨的现在,Text-to-SQL越来越重要了,所以今天就来聊聊Text-to-SQL。 Text-to-SQL是一种将自然语言查询转换为数据库查询的技术。它可以让用户通过自然语言来查询数据库,而不需要编写复杂的SQL语句。 T…...
【Linux】动静态库的制作与使用
一.对软硬链接的补充 1、无法对目录进行硬链接 为什么呢? 首先,我们在访问文件时,每一个文件都会有自己的dentry结构,这些结构会在内存中维护一棵路径树,来快速进行路径查找。但是如果某个节点直接使用硬链接到了根节…...
