二分查找到底快在哪:从猜数字到边界写法一次讲透
1. 二分算法到底快在哪先把问题想清楚再写代码刚入行的头两年我对二分算法的态度是能用就行。直到有一次线上排查一个库存扣减的接口数据量到了百万级遍历查找直接把响应时间拖到了秒级我才痛下决心把这个算法从头到尾捋了一遍。捋完之后发现二分这东西看着简单真正写对、写稳、写到能扛住边界的人其实不多。这篇就来聊聊我理解的二分算法尽量做到一学就懂、一写就会。先说说二分算法是什么。它的学名是二分查找也有人叫折半查找核心思路非常朴素在一个有序的序列里每次取中间位置的元素跟目标值比较根据比较结果把搜索范围砍掉一半如此反复直到找到目标或者范围为空。它解决的问题就是在一个有序集合里快速定位某个值适用场景包括有序数组查找、答案区间逼近、单调函数求根、资源分配的最优解搜索等等。它适合谁看我的判断是三类人一是刚开始学数据结构与算法、被各种边界条件折磨的新手二是刷题时能默写模板但一改就错的进阶者三是工作里需要处理大规模有序数据、想写出工业级稳定代码的工程师。三类人的痛点不一样但底层对二分的理解是共通的——区间怎么定义、循环什么时候停、边界怎么收缩这三件事想透了二分就不再是玄学。我个人的经验是二分算法的门槛不在看懂而在写对。你可能五分钟就能理解它的思想但很可能在接下来半年里反复因为mid取整方向、left和right的更新方式、循环终止条件而写出死循环或者漏解。所以这篇的重点会放在为什么这样写而不是单纯给你一个模板让你背。2. 从猜数字游戏理解二分思想其实一点不复杂2.1 一个生活场景把二分讲透我特别喜欢用猜数字游戏来解释二分。规则很简单我心里想一个 1 到 100 之间的整数你来猜我每次只告诉你大了小了或者猜对了。最笨的办法是从 1 开始一个一个猜运气差要猜 100 次。稍微聪明一点的人会先猜 50如果我说大了那答案一定在 1 到 49 之间刚才那一半直接被排除掉了接着猜 25再排除一半。最多 7 次就能锁定答案。这就是二分的全部精髓利用有序性这里是大小关系每次排除掉一半的候选区间。从 100 个候选到 1 个候选每次除以 2需要多少次log₂100 ≈ 6.64向上取整就是 7 次。这个数字不是巧合它就是二分算法的时间复杂度O(log n)的直观来源。把这个游戏翻译成代码语言候选区间就是数组的下标范围[left, right]每次猜的中间位置就是mid我的回答大了小了就对应着把right往左收或者把left往右收。你看算法思想本身没有任何高深的地方难点全在把区间这个概念在代码里表示准确。2.2 为什么必须是有序的单调性是二分的命根子很多人知道二分要求有序但没想过为什么。道理在于二分每次排除一半依赖的是一个确定的推断如果中间值比目标大那么比中间值更大的那一半一定都不可能是答案。这个推断成立的前提就是序列必须有序更准确地说是具备某种单调性。如果数组是无序的[3, 1, 4, 1, 5, 9, 2, 6]你取中间值 1发现它比目标 6 小你能说右边都大于 6吗不能右边还有 5、9、2 这些乱七八糟的值。推断不成立排除一半就是错的算法直接失效。这里我要补充一个进阶认知二分真正要求的不是数组有序而是你用来做判断的那个性质具有单调性。这是什么意思举个例子我们要在一个先递增后递减的数组里找峰值这个数组整体不有序但峰值左边单调递增、右边单调递减这个性质是单调的照样可以用二分。后面讲二分答案的时候你会更深刻地体会到这一点——很多题目里我们二分的对象根本不是数组而是一个抽象的答案区间。2.3 时间复杂度是怎么算出来的面试里经常被问二分的时间复杂度是多少怎么推导的很多人张口就是O(log n)但说不清推导过程。其实很简单。设数组长度为n第一次查找后剩余n/2第二次剩余n/4第k次剩余n / 2^k。当剩余元素个数降到 1 时结束也就是n / 2^k 1解得k log₂n。所以循环最多执行log₂n次每次循环内部只做了常数次比较和赋值总时间复杂度就是O(log n)。这个量级有多恐怖n 10^9十亿的时候log₂n ≈ 30。也就是说在十亿个有序数据里找一个数二分最多只要 30 次比较。而线性遍历最坏要十亿次。这就是为什么在海量有序数据场景下二分是无可替代的。我前面提到的库存扣减那个案例正是把线性查找换成了基于有序索引的二分定位响应时间从秒级降到了毫秒级。注意二分的时间复杂度优势建立在数据已经有序这个前提上。如果为了二分专门去排序那么排序本身的O(n log n)开销往往比一次线性查找还大。所以要不要用二分这件事得结合实际场景判断不是无脑上。3. 两种经典写法左闭右闭与左闭右开3.1 左闭右闭写法最符合直觉的一种区间表示法是二分最容易让人混乱的地方。所谓的左闭右闭指的是搜索区间用[left, right]表示左右两端的下标都是有效的、都在候选范围内。写成代码长这样def binary_search(nums, target): left, right 0, len(nums) - 1 # 区间 [left, right] while left right: # 区间非空时继续 mid left (right - left) // 2 if nums[mid] target: return mid elif nums[mid] target: left mid 1 # 目标在右半区mid 已排除 else: right mid - 1 # 目标在左半区mid 已排除 return -1这段代码里有三个关键点我逐一解释为什么这么写。第一right初始化为len(nums) - 1因为区间是闭的最后一个元素的下标就是len(nums) - 1。第二循环条件是left right因为当left right时区间里还有一个元素[left, left]还没查完必须继续。第三更新边界时是left mid 1和right mid - 1因为mid位置已经比较过了、可以确定不是答案所以要排除掉不能写成left mid。3.2 左闭右开写法工业代码里更常见左闭右开用[left, right)表示区间左端有效、右端无效。这种表示法在很多标准库比如 C 的迭代器区间里是主流代码长这样def binary_search(nums, target): left, right 0, len(nums) # 区间 [left, right) while left right: # 区间非空时继续 mid left (right - left) // 2 if nums[mid] target: return mid elif nums[mid] target: left mid 1 else: right mid # 注意这里是 mid 而不是 mid-1 return -1对比一下就能发现区别right初始化为len(nums)因为右端取不到循环条件是left right因为当left right时区间[left, left)已经是空的了最关键的是right更新时写的是right mid而不是right mid - 1因为mid本身就是开区间的边界、本来就不在候选范围里。我个人的体会是左闭右开在推导含重复元素的边界问题时会少很多心智负担因为开区间端点天然被排除这个语义和right mid的写法是自洽的。所以我给新手的建议是先死磕左闭右闭把逻辑理通然后长期使用左闭右开来写生产代码。3.3 两种写法怎么选一张表说清楚对比项左闭右闭[l, r]左闭右开[l, r)right 初值len(nums) - 1len(nums)循环条件left rightleft rightright 更新right mid - 1right mid区间空判定left rightleft right直觉友好度高中边界题稳定性中高选哪个都行关键是选定一种之后整道题、整个项目里保持一致。最怕的就是一会儿左闭右闭、一会儿左闭右开然后mid - 1、mid 1随手乱写不死循环才怪。我在 code review 里见过太多因为混用两种风格而写出的 bug这类问题往往隐蔽性极强、只在特定数据量下触发。

相关新闻

DeepSeek-V2-7B保险话术生成实战:合规、实时与情感精准闭环

DeepSeek-V2-7B保险话术生成实战:合规、实时与情感精准闭环

简介:本资源是一份面向保险科技从业者、AI算法工程师及数字化转型决策者的深度技术方案,系统阐述DeepSeek-V3大模型在保险销售全链路的落地实践,聚焦销售话术生成与客户情感分析两大核心能力,解决代理人话术合规性不足、客户意图识…

2026/9/30 4:55:12 阅读更多 →
iPhone真的能玩PC游戏吗?Madeira iOS x86模拟器实测结果深度解读

iPhone真的能玩PC游戏吗?Madeira iOS x86模拟器实测结果深度解读

iPhone真的能玩PC游戏吗?Madeira iOS x86模拟器实测结果深度解读 【免费下载链接】Madeira Run x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT 项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira Madeira 是一个运行在未越狱 iP…

2026/9/30 4:55:12 阅读更多 →
用Claude搭建AI备课工作流:从提示词到自动化教案生成

用Claude搭建AI备课工作流:从提示词到自动化教案生成

在教师圈子里,问得最多的不是“AI能不能帮我备课”,而是“AI到底怎么帮我备课”。过去一年,我陆续试过不少AI工具,也组织过教研组做小范围试点,最后真正能稳定留在日常工作里的,反而是最不起眼的流程化用法…

2026/9/30 4:54:11 阅读更多 →

最新新闻

Laya-MLX:Apple Silicon上的7.4ms端侧推理方案

Laya-MLX:Apple Silicon上的7.4ms端侧推理方案

1. 从打字延迟说起:为什么端侧推理突然成了热词最近在 Apple Silicon 上跑模型的朋友,应该都刷到了 Laya-MLX 这个东西。7.4ms 的极速文字决策延迟,听上去像营销数字,但真正在 M 系列芯片上跑过本地模型的人都明白,这个…

2026/9/30 5:33:30 阅读更多 →
天车AI监控实现主动智防:多源感知+闭环控制技术解析

天车AI监控实现主动智防:多源感知+闭环控制技术解析

1. 项目概述:这不是又一个“装摄像头报警”的老套路威盛发布天车安全AI监控方案,驱动工业安全“主动智防”革新——这句话里,“天车”“AI监控”“主动智防”三个词一出来,我就知道这绝不是把普通摄像头换个壳、加个“AI”标签就敢…

2026/9/30 5:33:30 阅读更多 →
Coding Agent 六层治理架构:从 AGENTS.md 到反馈闭环的工程实践

Coding Agent 六层治理架构:从 AGENTS.md 到反馈闭环的工程实践

1. 为什么需要给 Coding Agent 立规矩1.1 从“玩具”到“同事”的认知转变过去一年,我几乎把市面上主流的命令行编程助手用了个遍。从最早的 Copilot 补全,到后来能自主读写文件、执行命令的 Agent 形态,工具的能力边界扩张得非常快。但用得越…

2026/9/30 5:33:30 阅读更多 →
基于Java的物流管理系统设计与实现:Spring Boot + MyBatis实战

基于Java的物流管理系统设计与实现:Spring Boot + MyBatis实战

简介:基于Java物流管理系统的毕业设计文档,围绕电商成熟背景下物流公司订单管理系统展开,面向需要完成Java Web课程设计或毕业设计的计算机专业学生,也适合开发人员参考B/S架构管理系统设计思路。资源为单个doc文档,压…

2026/9/30 5:33:30 阅读更多 →
DDPG在航空器冲突解脱中的应用:强化学习空管仿真系统解析

DDPG在航空器冲突解脱中的应用:强化学习空管仿真系统解析

简介:这份资源是一篇面向民航智能空管领域技术人员与算法研究者的方法类文档,重点探讨基于深度强化学习DDPG的航空器冲突解脱方案。针对空中交通流量持续增长带来的高密度空域防撞难题,文档提出通过OpenScope开源空管平台构建仿真场景&#x…

2026/9/30 5:33:30 阅读更多 →
工控AI应用实战:六个场景切片赋能产线工程师

工控AI应用实战:六个场景切片赋能产线工程师

1. 这不是“学AI”,而是工控人重新校准职业坐标的实战课“工控国际举办全员AI应用能力提升专题培训”——看到这个标题,我第一反应不是点开看PPT长什么样,而是下意识摸了摸自己电脑里那几个常年没更新的PLC仿真软件、SCADA组态工程备份包&…

2026/9/30 5:32:29 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →