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

从三道经典二分题,彻底搞懂「二分查找」的两种核心写法

从三道经典二分题彻底搞懂「二分查找」的两种核心写法二分查找是算法面试的「敲门砖」也是很多人「一看就会一写就废」的重灾区。很多人卡在边界条件、mid计算、循环终止条件上本质是没搞懂二分的两种核心模板。今天我们就通过LeetCode上三道经典二分题彻底拆解二分查找的两种写法帮你彻底吃透这个算法。文章目录从三道经典二分题彻底搞懂「二分查找」的两种核心写法一、先搞懂二分查找的两种核心模板模板1左闭右闭 [left, right]模板2左闭右开 [left, right)模板3向上取整的「找右边界」模板二、题目1x的平方根LeetCode 69题目描述思路分析代码实现逐行注释关键细节拆解三、题目2搜索插入位置LeetCode 35题目描述思路分析代码实现逐行注释关键细节拆解四、题目3山脉数组的峰顶索引LeetCode 852题目描述思路分析代码实现逐行注释关键细节拆解五、三种模板的对比与选型指南选型口诀六、二分查找的避坑指南七、总结一、先搞懂二分查找的两种核心模板二分查找的本质是通过不断缩小搜索区间逼近目标值。根据区间的定义和终止条件我们可以把二分分为两种最常用的模板模板1左闭右闭[left, right]区间定义搜索区间是包含左右端点的闭区间循环条件while (left right)区间收缩当nums[mid] target时目标在右半区left mid 1当nums[mid] target时目标在左半区right mid - 1特点逻辑直观适合「精确查找目标值」的场景模板2左闭右开[left, right)区间定义搜索区间是包含左端点、不包含右端点的半开区间循环条件while (left right)区间收缩当nums[mid] target时目标在右半区left mid 1当nums[mid] target时目标在左半区right mid特点边界处理更统一适合「找满足条件的第一个/最后一个位置」的场景模板3向上取整的「找右边界」模板核心mid left (right - left 1) / 2向上取整循环条件while (left right)适用场景找最后一个满足条件的位置避免死循环区间收缩满足条件时left mid保留mid继续向右找不满足条件时right mid - 1排除mid向左找二、题目1x的平方根LeetCode 69题目描述给你一个非负整数x计算并返回x的 算术平方根 。由于返回类型是整数结果只保留整数部分小数部分将被舍去。注意不允许使用任何内置指数函数和算符例如pow(x, 0.5)或者x ** 0.5。思路分析我们要找的是最大的整数k满足k² ≤ x这是一个典型的「找右边界」问题完美适配向上取整的二分模板。代码实现逐行注释classSolution{public:intmySqrt(intx){// 特殊情况0和1的平方根就是本身直接返回if(x1)return0;// 搜索区间[1, x]因为平方根一定在1到x之间intleft1,rightx;// 循环条件left right当left right时区间收敛到目标值while(leftright){// 核心向上取整计算mid避免死循环// 公式mid left (right - left 1) / 2// 等价于 (left right 1) / 2用前者避免int溢出longlongmidleft(right-left1)/2;// 判断mid的平方是否xif(mid*midx){// 满足条件mid可能是答案保留mid向右继续找更大的kleftmid;}else{// 不满足条件mid太大排除mid向左找rightmid-1;}}// 循环结束时left right就是我们要找的最大kreturnleft;}};关键细节拆解为什么用long long mid当x接近2^31-1时mid*mid会超过int的最大值导致溢出用long long可以安全计算。为什么要向上取整假设left2, right3如果用普通向下取整mid(23)/22当mid*mid x时leftmid2会陷入死循环。向上取整后mid3要么left3跳出循环要么right2跳出循环完美解决死循环问题。为什么最后返回left循环结束时left right这个值就是满足k² ≤x的最大整数也就是我们要的平方根的整数部分。三、题目2搜索插入位置LeetCode 35题目描述给定一个排序数组和一个目标值在数组中找到目标值并返回其索引。如果目标值不存在于数组中返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(log n)的算法。思路分析我们要找的是第一个大于等于target的位置这是一个典型的「找左边界」问题适配左闭右开的二分模板。代码实现逐行注释classSolution{public:intsearchInsert(vectorintnums,inttarget){// 搜索区间[0, nums.size()-1]左闭右闭intleft0,rightnums.size()-1;// 循环条件left right区间收敛到一个元素while(leftright){// 普通向下取整计算mid找左边界用向下取整intmidleft(right-left)/2;if(nums[mid]target){// mid及左边都小于target目标在右半区left右移leftmid1;}else{// mid及右边都大于等于target目标在左半区right左移到midrightmid;}}// 循环结束后left right需要判断最后一个元素是否小于target// 如果小于说明target比所有元素都大插入到末尾left1// 否则left就是第一个target的位置if(nums[left]target)returnleft1;returnleft;}};关键细节拆解为什么最后要加判断当target比数组所有元素都大时循环结束后left right nums.size()-1此时nums[left] target所以插入位置是left1也就是数组末尾。为什么用左闭右开模板这个模板天然适合「找第一个满足条件的位置」边界处理更统一不需要考虑right mid-1的复杂情况。时间复杂度O(log n)每次循环区间缩小一半完美符合题目要求。四、题目3山脉数组的峰顶索引LeetCode 852题目描述符合下列属性的数组arr称为山脉数组arr.length 3存在i0 i arr.length - 1使得arr[0] arr[1] ... arr[i - 1] arr[i]arr[i] arr[i 1] ... arr[arr.length - 1]给你由整数组成的山脉数组arr返回任何满足arr[0] arr[1] ... arr[i - 1] arr[i] arr[i 1] ... arr[arr.length - 1]的下标i。你必须设计并实现时间复杂度为O(log(n))的解决方案。思路分析山脉数组的特点是严格递增到峰顶然后严格递减我们要找的是峰顶的索引也就是「最后一个满足arr[mid] arr[mid-1]的位置」同样是「找右边界」问题用向上取整的二分模板。代码实现逐行注释classSolution{public:intpeakIndexInMountainArray(vectorintarr){// 搜索区间[1, arr.size()-2]// 因为峰顶一定不在0和最后一个位置山脉数组要求0 i arr.length-1intleft1,rightarr.size()-2;// 循环条件left right区间收敛到目标值while(leftright){// 向上取整计算mid避免死循环intmidleft(right-left1)/2;if(arr[mid]arr[mid-1]){// mid在上升区间峰顶在mid或右边保留mid向右找leftmid;}else{// mid在下降区间峰顶在mid左边排除mid向左找rightmid-1;}}// 循环结束时left right就是峰顶的索引returnleft;}};关键细节拆解为什么初始区间是[1, arr.size()-2]山脉数组的峰顶一定不在第一个和最后一个位置所以直接排除这两个位置缩小搜索区间提高效率。为什么用arr[mid] arr[mid-1]作为判断条件对于山脉数组上升区间的元素一定满足arr[mid] arr[mid-1]下降区间的元素一定满足arr[mid] arr[mid-1]用这个条件可以精准判断mid在上升还是下降区间。为什么用向上取整同样是为了避免死循环当left right-1时向上取整会让mid right要么left right跳出循环要么right mid-1 left跳出循环完美解决边界问题。五、三种模板的对比与选型指南看完三道题我们来总结一下三种模板的适用场景帮你快速选型模板类型mid计算方式循环条件核心适用场景典型题目左闭右闭mid left (right - left) / 2while (left right)精确查找目标值普通二分查找左闭右开找左边界mid left (right - left) / 2while (left right)找第一个满足条件的位置搜索插入位置向上取整找右边界mid left (right - left 1) / 2while (left right)找最后一个满足条件的位置x的平方根、山脉数组选型口诀精确查找用闭区间左右边界用开区间找左边界向下取整找右边界向上取整循环结束leftright统一返回left六、二分查找的避坑指南溢出问题永远用mid left (right - left) / 2代替(left right) / 2避免int溢出。死循环问题找右边界时必须用向上取整否则会陷入leftmid的死循环。区间定义一致性整个算法过程中区间的定义必须保持一致不能一会闭区间一会开区间。特殊情况处理一定要处理边界情况比如x0、数组为空、target比所有元素大等。七、总结二分查找的核心不是「代码怎么写」而是「区间怎么定义」。只要搞懂了区间的定义边界条件就迎刃而解了。通过这三道经典题目我们彻底拆解了二分查找的三种核心模板掌握了「找左边界」「找右边界」「精确查找」的写法以后再遇到二分题就能快速选型写出无bug的代码。二分查找是算法的基础也是面试的高频考点吃透这三种模板你就搞定了90%的二分题。

相关文章:

从三道经典二分题,彻底搞懂「二分查找」的两种核心写法

从三道经典二分题,彻底搞懂「二分查找」的两种核心写法 二分查找是算法面试的「敲门砖」,也是很多人「一看就会,一写就废」的重灾区。很多人卡在边界条件、mid计算、循环终止条件上,本质是没搞懂二分的两种核心模板。 今天我们就…...

为什么BiliTools能成为哔哩哔哩内容管理的最佳选择?3大核心优势解析

为什么BiliTools能成为哔哩哔哩内容管理的最佳选择?3大核心优势解析 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/Bil…...

开源成就管理神器:SteamAchievementManager的全方位问题解决方案

开源成就管理神器:SteamAchievementManager的全方位问题解决方案 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 在游戏体验中,玩家…...

如何利用WebSocket实现biliup的实时直播状态监控与日志推送:完整指南

如何利用WebSocket实现biliup的实时直播状态监控与日志推送:完整指南 【免费下载链接】biliup 自动直播录制、投稿、twitch、ytb频道搬运工具。命令行投稿(B站)和视频下载工具,提供多种登录方式,支持多p。 项目地址: https://gitcode.com/g…...

终极指南:raylib轻量级游戏开发库的快速上手与实战应用

终极指南:raylib轻量级游戏开发库的快速上手与实战应用 【免费下载链接】raylib A simple and easy-to-use library to enjoy videogames programming 项目地址: https://gitcode.com/GitHub_Trending/ra/raylib raylib是一个简单易用的游戏编程库&#xff0…...

2026年阿里云2分钟超速步骤:OpenClaw搭建及大模型API Key、Skill集成

2026年阿里云2分钟超速步骤:OpenClaw搭建及大模型API Key、Skill集成。OpenClaw作为2026年主流的AI自动化助理平台,可通过阿里云轻量服务器实现724小时稳定运行,并快速接入钉钉,让AI在企业群聊、个人工作流中自动执行任务、处理消…...

CD4(分化簇4):免疫共受体的核心机制与抗体药物研发逻辑

CD4(分化簇4,Cluster of Differentiation 4)作为辅助性T细胞的关键标志物与免疫应答的核心共受体,不仅在适应性免疫中扮演“指挥官”角色,更是感染性疾病与自身免疫病药物研发的重要靶点。本文从分子结构、信号转导机制…...

如何实现真实感前端游戏碰撞响应:从弹性到摩擦的完整指南

如何实现真实感前端游戏碰撞响应:从弹性到摩擦的完整指南 【免费下载链接】frontend-stuff 📝 A continuously expanded list of frameworks, libraries and tools I used/want to use for building things on the web. Mostly JavaScript. 项目地址: …...

OpenClaw自动化测试:Qwen3-14B驱动的代码审查机器人

OpenClaw自动化测试:Qwen3-14B驱动的代码审查机器人 1. 为什么需要自动化代码审查 去年参与一个开源项目时,我经常在深夜提交代码后收到维护者的评论:"这里有个拼写错误"、"那个变量命名不规范"。这种延迟反馈让我意识…...

重构手游操控体验:Escrcpy如何颠覆手机游戏交互范式

重构手游操控体验:Escrcpy如何颠覆手机游戏交互范式 【免费下载链接】escrcpy 📱 Display and control your Android device graphically with scrcpy. 项目地址: https://gitcode.com/GitHub_Trending/es/escrcpy 在移动游戏日益复杂的今天&…...

如何用GetQzonehistory永久备份你的QQ空间回忆?三步轻松搞定

如何用GetQzonehistory永久备份你的QQ空间回忆?三步轻松搞定 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否担心多年积累的QQ空间说说、照片和评论会随着时间流逝而消…...

终极Cubism.js部署指南:从开发到生产环境的完整实践方案

终极Cubism.js部署指南:从开发到生产环境的完整实践方案 【免费下载链接】cubism Cubism.js: A JavaScript library for time series visualization. 项目地址: https://gitcode.com/gh_mirrors/cu/cubism Cubism.js是一款强大的JavaScript时间序列可视化库&…...

ReTerraForged终极指南:如何在Minecraft 1.20+中打造专业级真实地形

ReTerraForged终极指南:如何在Minecraft 1.20中打造专业级真实地形 【免费下载链接】ReTerraForged a 1.19 port of https://github.com/TerraForged/TerraForged 项目地址: https://gitcode.com/gh_mirrors/re/ReTerraForged ReTerraForged作为Minecraft 1.…...

终极指南:如何快速配置Cubism.js连接Ganglia数据源实现系统监控可视化

终极指南:如何快速配置Cubism.js连接Ganglia数据源实现系统监控可视化 【免费下载链接】cubism Cubism.js: A JavaScript library for time series visualization. 项目地址: https://gitcode.com/gh_mirrors/cu/cubism Cubism.js是一款强大的JavaScript时间…...

别再忍受龟速下载!保姆级教程:Ubuntu 18.04一键更换阿里云/清华源(附SSH无桌面操作)

Ubuntu 18.04国内软件源极速配置指南:告别蜗牛速度的终极方案 每次执行apt update时盯着缓慢爬升的进度条,是否让你产生砸键盘的冲动?作为国内Ubuntu用户,默认国际源的龟速下载堪称开发效率的头号杀手。本文将彻底解决这个痛点——…...

StructBERT在金融舆情监控系统中的实时分类方案

StructBERT在金融舆情监控系统中的实时分类方案 1. 引言 金融市场的波动往往源于信息的快速传播。一条突发的负面新闻可能在几分钟内引发股价大幅波动,而一个利好消息也可能在瞬间推动市场情绪高涨。传统的金融舆情监控系统往往面临响应延迟的挑战,等到…...

LANCZOS智能压缩+RGB自动转换:Anything to RealCharacters预处理模块详解

LANCZOS智能压缩RGB自动转换:Anything to RealCharacters预处理模块详解 1. 项目概述 Anything to RealCharacters是一款专为RTX 4090显卡设计的2.5D转真人图像转换系统。该系统基于通义千问Qwen-Image-Edit-2511图像编辑模型,集成了专门优化的写实化权…...

终极指南:3分钟上手res-downloader,轻松下载全网视频音频资源

终极指南:3分钟上手res-downloader,轻松下载全网视频音频资源 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-download…...

3种RPA文件解包实战技巧:从游戏资源提取到技术深潜的完整指南

3种RPA文件解包实战技巧:从游戏资源提取到技术深潜的完整指南 【免费下载链接】unrpa A program to extract files from the RPA archive format. 项目地址: https://gitcode.com/gh_mirrors/un/unrpa 当你沉浸在视觉小说的世界中,是否曾好奇那些…...

ai辅助qt性能优化:让快马平台帮你设计多线程数据可视化方案

最近在开发一个Qt实时数据可视化应用时,遇到了主界面卡顿的问题。经过分析发现,数据采集和处理操作直接在主线程执行,导致UI响应延迟。通过InsCode(快马)平台的AI辅助功能,我快速获得了一个多线程优化方案,效果显著。这…...

UE4新手必看:5分钟搞定角色沿Spline路径移动动画(附Level Sequence配置)

UE4路径动画实战:从Spline绑定到Level Sequence高级配置 在游戏开发中,让角色沿着预设路径移动是过场动画和游戏机制设计的常见需求。本文将带你深入UE4的Spline路径动画系统,不仅解决基础实现问题,还会分享几个提升动画质量的实用…...

Zotero Reference:重新定义学术文献管理效率的开源工具

Zotero Reference:重新定义学术文献管理效率的开源工具 【免费下载链接】zotero-reference PDF references add-on for Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-reference 一、5大核心价值:为什么Zotero Reference是研究者的…...

GoWorld网络协议详解:TCP、KCP与WebSocket的多协议支持实现

GoWorld网络协议详解:TCP、KCP与WebSocket的多协议支持实现 【免费下载链接】goworld Scalable Distributed Game Server Engine with Hot Swapping in Golang 项目地址: https://gitcode.com/gh_mirrors/go/goworld GoWorld是一个用Go语言开发的可扩展分布式…...

AI Agent与边缘计算结合:低延迟场景下的智能体部署方案

AI Agent与边缘计算结合:低延迟场景下的智能体部署方案 关键词:AI Agent、边缘计算、低延迟部署、模型压缩、资源调度、隐私计算、多智能体协同 摘要:本文将像给小学生讲“快递柜前置配送奶茶”的故事一样,深入浅出地解释AI Agent和边缘计算是什么、为什么要把它们结合、如…...

arq源码解析:深入理解异步作业队列的实现原理

arq源码解析:深入理解异步作业队列的实现原理 【免费下载链接】arq Fast job queuing and RPC in python with asyncio and redis. 项目地址: https://gitcode.com/gh_mirrors/ar/arq arq是一个基于Python asyncio和Redis构建的高性能异步作业队列系统&#…...

nginx-proxy-automation升级与迁移指南:平滑过渡到新版本

nginx-proxy-automation升级与迁移指南:平滑过渡到新版本 【免费下载链接】nginx-proxy-automation Automated docker nginx proxy integrated with letsencrypt. 项目地址: https://gitcode.com/gh_mirrors/ng/nginx-proxy-automation nginx-proxy-automati…...

如何快速集成JCameraView:5分钟实现微信级拍照功能

如何快速集成JCameraView:5分钟实现微信级拍照功能 【免费下载链接】CameraView 仿微信拍照Android控件(轻触拍照,长按摄像) 项目地址: https://gitcode.com/gh_mirrors/cam/CameraView JCameraView是一款仿微信拍照的Andr…...

终极指南:如何在DevOps中高效使用curl进行CI/CD流水线和监控集成

终极指南:如何在DevOps中高效使用curl进行CI/CD流水线和监控集成 【免费下载链接】curl A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQ…...

避坑指南:Gazebo仿真中Cartographer 3D建图不成功?检查这5个关键点(传感器配置、launch文件、地图保存)

Gazebo仿真中Cartographer 3D建图五大疑难解析:从传感器配置到地图保存全攻略 当你在Gazebo中启动Cartographer 3D建图时,是否遇到过rviz界面一片空白?或是建图过程中机器人轨迹突然断裂?这些看似简单的现象背后,往往…...

终极GoogleTest死亡测试指南:如何轻松掌握程序异常退出测试技巧

终极GoogleTest死亡测试指南:如何轻松掌握程序异常退出测试技巧 【免费下载链接】googletest GoogleTest - Google Testing and Mocking Framework 项目地址: https://gitcode.com/GitHub_Trending/go/googletest GoogleTest(Google Testing and …...