【算法】二分查找算法详解与模板总结:从原理到变体,一篇就够了

【算法】二分查找算法详解与模板总结:从原理到变体,一篇就够了

目录

二分查找算法详解

二分查找(Binary Search)是一种在有序数组中查找特定元素的高效算法。它的核心思想是分而治之,每次将搜索范围缩小一半。

基本原理

想象你在查英语字典找"apple"这个词:

  1. 翻开字典的中间
  2. 如果这一页的单词在"apple"之前,就往后翻
  3. 如果这一页的单词在"apple"之后,就往前翻
  4. 重复这个过程,直到找到"apple"

这就是二分查找的生活例子。

算法步骤

假设有一个升序数组 arr,要查找目标值 target

  1. 初始化左指针 left = 0,右指针 right = n-1
  2. left <= right 时循环:
    • 计算中间位置 mid = left + (right - left) / 2(防止整数溢出)
    • 如果 arr[mid] == target,找到目标,返回 mid
    • 如果 arr[mid] < target,说明目标在右半部分,left = mid + 1
    • 如果 arr[mid] > target,说明目标在左半部分,right = mid - 1
  3. 循环结束未找到,返回 -1

代码实现

基础版本(查找精确值)

intbinarySearch(vector<int>& nums,int target){int left =0;int right = nums.size()-1;while(left <= right){// 避免 (left + right) 可能溢出int mid = left +(right - left)/2;if(nums[mid]== target){return mid;// 找到目标}elseif(nums[mid]< target){ left = mid +1;// 目标在右半部分}else{ right = mid -1;// 目标在左半部分}}return-1;// 未找到}

时间复杂度分析

  • 时间复杂度:O(log n)
    • 每次比较后,搜索范围减半
    • 对于大小为 n 的数组,最多需要 log₂(n) 次比较
  • 空间复杂度:O(1)
    • 只需要常数级别的额外空间

二分查找的变体

1. 查找第一个等于目标的位置

intfindFirst(vector<int>& nums,int target){int left =0, right = nums.size()-1;int result =-1;while(left <= right){int mid = left +(right - left)/2;if(nums[mid]== target){ result = mid;// 记录当前位置 right = mid -1;// 继续向左查找}elseif(nums[mid]< target){ left = mid +1;}else{ right = mid -1;}}return result;}

2. 查找最后一个等于目标的位置

intfindLast(vector<int>& nums,int target){int left =0, right = nums.size()-1;int result =-1;while(left <= right){int mid = left +(right - left)/2;if(nums[mid]== target){ result = mid;// 记录当前位置 left = mid +1;// 继续向右查找}elseif(nums[mid]< target){ left = mid +1;}else{ right = mid -1;}}return result;}

3. 查找第一个大于等于目标的位置

intfindFirstGreaterOrEqual(vector<int>& nums,int target){int left =0, right = nums.size()-1;while(left <= right){int mid = left +(right - left)/2;if(nums[mid]>= target){ right = mid -1;// 虽然满足条件,但继续向左找更小的}else{ left = mid +1;// 当前太小,向右找}}return left;// left 就是第一个 >= target 的位置}

常见应用场景

  1. 有序数组的查找 - 最基础的应用
  2. 求平方根 - 在 0 到 x 之间二分查找
  3. 旋转数组的查找 - 如 [4,5,6,7,0,1,2] 中查找
  4. 寻找峰值 - 在山峰数组中找到最大值
  5. 在答案空间二分 - 如"找到最小速度使得在规定时间内完成任务"

注意事项和常见错误

  1. 循环条件left <= right vs left < right 的选择
  2. 边界更新left = mid + 1right = mid - 1 要正确
  3. 整数溢出:使用 mid = left + (right - left) / 2 而非 (left + right) / 2
  4. 数组必须有序:二分查找的前提是有序,否则结果错误
  5. 重复元素:处理重复元素时要明确需求(找第一个/最后一个)

二分查找虽然原理简单,但细节容易出错。建议多练习不同类型的题目,熟练掌握各种变体的写法。

二分算法模板总结

在这里插入图片描述
//找左边while(left < right){int mid = left +(right - left)/2;//左边if(nums[mid]>= target) right = mid;//右边else left = mid +1;}//找右边while(left < right){int mid = left +(right - left+1)/2;//右边if(nums[mid]<= target) left = mid;//左边else right = mid -1;}

实战练习题目(含链接)

⼆分查找(easy)
在排序数组中查找元素的第⼀个和最后⼀个位置(medium)
搜索插⼊位置(easy)
x 的平⽅根(easy)
⼭峰数组的峰顶(easy)
寻找峰值(medium)
搜索旋转排序数组中的最⼩值(medium)
0〜n-1 中缺失的数字(easy)

Read more

【扣子Coze教程】“葬经人”动画工作流开源(附提示词)

【扣子Coze教程】“葬经人”动画工作流开源(附提示词)

最近扣子更新了大版本,送了很多积分,根本用不完。 于是我研究了下“葬经人”动画短视频,看能不能用工作流搞定,结果没一会跑通了,那还说啥,直接开源! 接下来就分享这个巨硬核的Coze工作流:一键生成“葬经人”风格动画短视频。 0代码,所有提示词均已给出,按步骤即可轻松复刻。 开始前,先简单介绍下这个“葬经人”博主,靠着清醒人性哲学短视频涨粉几十万,非常牛逼。 工作流完整截图: 节点看着有点多,别被吓到,没有代码,无非就是拖拉拽节点和填几个参数。 分段展示下工作流: 01 制作工作流 (1)登录扣子,创建一个工作流; 地址:https://www.coze.cn/ (2)设置开始节点参数; (3)添加一个大模型节点->重命名为文案生成->设置参数; 提示💡:都是按顺序在前一个节点后面添加(比如这一步添加的大模型连接在开始节点后)

By Ne0inhk

VS Code 编辑器 Git 工具 - 分支操作【保姆级教程】

VS Code 编辑器 Git 工具 - 分支操作 1、查看分支 2、分支提交记录 3、 以当前分支创建并发布分支 发布后 4、 切换分支 1. 切换分支时记得先提交当前分支的代码 2. 点击分支列表中的分支名称即可切换分支 5、 以某分支创建新分支 6、 合并分支 合并成功,branch1-1分支的test1.txt 合并到branch1分支 7、 变基分支 1. 变基操作时确保当前分支的代码已提交 2. 遇到代码冲突时选择适合的合并方式解决代码冲突,这里我选择【保留双方更改】 3. 变基一半不想变基了,放弃更改文件就行,或者进行文件回退重新选择合并方式 变基成功,branch1-1的提交合并到了branch1 8、 重命名分支 1. 重命名分支是命名当前分支 2. 选择重命名分支后一定要发布分支,不然远程分支名称未同步 9、

By Ne0inhk

最近爆火的 OpenClaw Skills 合集开源了!已收录 700+!

在介绍这份令人眼花缭乱的“武器库”之前,先给还不了解 OpenClaw 的朋友补个课。 简单来说,OpenClaw 是目前 GitHub 上最火的本地化 AI Agent 平台(前身是 Clawd/Moltbot)。不同于只能在网页里陪聊的 ChatGPT,OpenClaw 是一个运行在你电脑终端里的“数字管家”。 * 本地优先:直接运行在你的 Mac/Linux/Windows 上,数据不出本地,拥有 Docker 沙箱级安全保护。 * 全渠道接入:你可以通过 WhatsApp、Telegram、Slack 甚至 iMessage 随时指挥它。 * 行动派:它不只是给你建议,而是能直接读写文件、运行命令、调用 API。 如果说 OpenClaw 是一个强悍的操作系统,那么下面要介绍的

By Ne0inhk

Gitee完全新手教程

文章目录 * 🚀 Gitee完全新手教程 * 一、注册与准备 * 二、创建第一个仓库(详细步骤) * 步骤1:点击创建按钮 * 步骤2:填写基础信息 * 步骤3:关键设置 * 步骤4:创建完成 * 三、本地操作指南 * 1. 克隆仓库到本地 * 2. 日常工作流程 * 3. 常用命令总结 * 四、重要概念解释 * 1. 仓库(Repository) * 2. 分支(Branch) * 3. 提交(Commit) * 4. 推送(Push)和拉取(Pull) * 五、新手注意事项 ⚠️ * 🚫 绝对不要做 * ✅ 推荐做法 * 六、.gitignore模板示例 * 七、遇到问题怎么办? * 常见问题解决 * 八、学习路径建议

By Ne0inhk