news 2026/1/27 11:00:43

二分查找——算法总结与教学指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二分查找——算法总结与教学指南

📚 算法核心思想

二分查找的本质

  • 有序集合中通过不断折半缩小搜索范围
  • 每次比较都能排除一半的错误答案
  • 核心前提:数据必须有序(直接或间接)

三种二分查找模式

模式特点适用场景关键判断
标准二分查找确切存在的值有序数组查找nums[mid] == target
寻找边界查找第一个/最后一个位置重复元素、插入位置条件变化时的边界处理
抽象二分在抽象条件上二分答案有单调性、最优化问题定义判定函数

🔧 通用解题框架

基础二分查找模板

intbinarySearch(vector<int>&nums,inttarget){intleft=0,right=nums.size()-1;while(left<=right){intmid=left+(right-left)/2;// 防止溢出if(nums[mid]==target){returnmid;// 找到目标}elseif(nums[mid]<target){left=mid+1;// 搜索右半部分}else{right=mid-1;// 搜索左半部分}}return-1;// 未找到}

寻找边界的二分模板

// 寻找第一个 >= target 的位置(lower_bound)intfindFirstGreaterOrEqual(vector<int>&nums,inttarget){intleft=0,right=nums.size();// 注意:右开区间while(left<right){intmid=left+(right-left)/2;if(nums[mid]>=target){right=mid;// 保留mid,继续向左找}else{left=mid+1;// 向右找}}returnleft;// 第一个 >= target 的位置}

🎯 问题识别技巧

什么时候用二分查找?

  1. 明显关键词:有序、排序、搜索、查找
  2. 数据规模大:O(n) 会超时,需要 O(log n)
  3. 答案单调性:条件满足性随参数单调变化

判断依据

// 如果是这些问题,考虑二分查找:-"在排序数组中查找元素的第一个和最后一个位置"-"寻找旋转排序数组中的最小值"-"在 D 天内送达包裹的能力"(最优化问题)-"制作 m 束花所需的最少天数"-"分割数组的最大值"

🔍 关键决策点

1. 如何选择区间表示?

  • 左闭右闭[left, right]while(left <= right),更新时mid±1
  • 左闭右开[left, right)while(left < right),更新时left=mid+1right=mid

2. 如何判断搜索方向?

// 不同问题的判断条件if(nums[mid]==target)// 标准查找if(nums[mid]>=target)// 寻找左边界if(nums[mid]>target)// 寻找右边界if(canFinish(piles,mid,h))// 最优化问题(抽象条件)

3. 如何避免死循环?

  • 确保每次循环区间都在缩小
  • 注意mid的计算方式:mid = left + (right-left)/2(向下取整)
  • 更新边界时至少移动一步:left = mid+1right = mid-1

💡 经典问题分类与解法

类型1:精确查找

// 问题:在排序数组中查找目标值intsearch(vector<int>&nums,inttarget){intleft=0,right=nums.size()-1;while(left<=right){intmid=left+(right-left)/2;if(nums[mid]==target)returnmid;elseif(nums[mid]<target)left=mid+1;elseright=mid-1;}return-1;}

类型2:寻找边界

// 问题:在排序数组中查找元素的第一个和最后一个位置vector<int>searchRange(vector<int>&nums,inttarget){// 找左边界:第一个 >= target 的位置intleft=lower_bound(nums.begin(),nums.end(),target)-nums.begin();// 找右边界:第一个 > target 的位置 - 1intright=upper_bound(nums.begin(),nums.end(),target)-nums.begin()-1;if(left<=right)return{left,right};return{-1,-1};}

类型3:旋转数组查找

// 问题:搜索旋转排序数组intsearchRotated(vector<int>&nums,inttarget){intleft=0,right=nums.size()-1;while(left<=right){intmid=left+(right-left)/2;if(nums[mid]==target)returnmid;// 判断哪一部分是有序的if(nums[left]<=nums[mid]){// 左半部分有序if(nums[left]<=target&&target<nums[mid]){right=mid-1;// 目标在有序的左半部分}else{left=mid+1;// 目标在右半部分}}else{// 右半部分有序if(nums[mid]<target&&target<=nums[right]){left=mid+1;// 目标在有序的右半部分}else{right=mid-1;// 目标在左半部分}}}return-1;}

类型4:最优化问题(抽象二分)

// 问题:在 D 天内送达包裹的能力intshipWithinDays(vector<int>&weights,intdays){// 确定二分搜索边界intleft=*max_element(weights.begin(),weights.end());// 最小能力intright=accumulate(weights.begin(),weights.end(),0);// 最大能力while(left<right){intmid=left+(right-left)/2;if(canShip(weights,days,mid)){right=mid;// 尝试更小的能力}else{left=mid+1;// 需要更大的能力}}returnleft;}boolcanShip(vector<int>&weights,intdays,intcapacity){intcurrent=0,needed=1;for(intweight:weights){if(current+weight>capacity){needed++;current=0;}current+=weight;}returnneeded<=days;}

🚀 教学要点

给初学者的建议

  1. 从理解原理开始

    二分查找为什么是 O(log n)? 每次比较排除一半元素 → 最多 log₂n 次
  2. 掌握两种模板

    • 模板1:精确查找(闭区间)
    • 模板2:边界查找(左闭右开)
  3. 手动模拟过程

    数组:[1,3,5,7,9,11]查找:7步骤1:left=0,right=5,mid=2,nums[2]=5<7→ left=3步骤2:left=3,right=5,mid=4,nums[4]=9>7→ right=3步骤3:left=3,right=3,mid=3,nums[3]=7==7→ 找到
  4. 注意常见陷阱

    • 整数溢出:使用mid = left + (right-left)/2
    • 死循环:确保每次循环边界都在变化
    • 边界条件:空数组、单个元素、目标不存在

二分查找的思维转换

  1. 从"找答案"到"猜答案+验证"

    传统:直接找到正确答案 二分:猜一个答案 → 验证是否正确 → 调整猜测
  2. 判定函数的编写

    // 最优化问题的关键:编写判定函数boolisValid(intguess){// 判断 guess 是否满足条件// 通常需要 O(n) 或 O(m) 的验证}

练习题进阶路径

Level 1: 基础二分查找(704题) Level 2: 寻找边界(34题) Level 3: 旋转数组搜索(33、81题) Level 4: 抽象二分查找(875、1011题) Level 5: 二维二分查找(74、240题) Level 6: 复杂最优化问题(410、1231题)

📝 一句话总结各类问题

  1. 标准二分:有序数组中找目标值
  2. 寻找边界lower_boundupper_bound的运用
  3. 旋转数组:先判断哪边有序,再决定搜索方向
  4. 峰值查找:比较 mid 和 mid+1,向更高的方向搜索
  5. 最优化问题:二分搜索答案,编写判定函数验证
  6. 二维二分:将二维映射到一维,或行列分别二分

🎁 终极心法

二分查找 = 有序数据 + 折半排除 + 边界处理

四步解题法

  1. 判断是否能用二分:数据是否有序?答案是否有单调性?
  2. 确定搜索范围:最小可能值和最大可能值是什么?
  3. 编写判定函数:如何验证一个猜测值是否可行?
  4. 处理边界情况:空数组、找不到、重复元素等

调试技巧

// 在循环中添加打印,观察搜索过程while(left<=right){intmid=left+(right-left)/2;cout<<"left="<<left<<", right="<<right<<", mid="<<mid<<", nums[mid]="<<nums[mid]<<endl;// ...}

掌握二分查找的关键在于理解其"减而治之"的思想,并通过大量练习熟悉各种变体。从标准二分开始,逐步挑战更复杂的问题,最终能够灵活运用二分思想解决各类最优化问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/23 11:10:00

Kimi生成的论文AI率爆表?这份降重操作指南收好

Kimi生成的论文AI率爆表&#xff1f;这份降重操作指南收好 TL;DR&#xff1a;Kimi生成的论文直接提交&#xff0c;AI率基本在70%以上。单靠Kimi自己改写只能降到15%-25%&#xff0c;想降到安全线以下必须配合专业降AI率工具。本文教你Kimi嘎嘎降AI/比话降AI的组合打法&#xff…

作者头像 李华
网站建设 2026/1/19 6:13:32

滚珠丝杆选型:导程与负载参数搭配需避开哪些常见误区?

在工业自动化设备的核心传动部件中&#xff0c;滚珠丝杆的选型直接决定了设备的精度、寿命和运行稳定性。很多工程师在选型时容易陷入导程与负载参数搭配的误区&#xff0c;导致设备后期出现精度漂移、磨损过快等问题。作为深耕传动领域25年的专业经销商&#xff0c;海威机电是…

作者头像 李华
网站建设 2026/1/23 8:15:51

AI应用架构师必看:智能质量控制平台为什么90%的项目死在数据层?

AI应用架构师必看:智能质量控制平台为什么90%的项目死在数据层? 一、引言:从“经验翻车”到“数据救命”的质检革命 凌晨3点,某新能源汽车工厂的质检车间依然灯火通明。生产线末端的机械臂正将刚组装好的电池包逐一送到人工质检台,8名质检员戴着放大镜,盯着电池表面的划…

作者头像 李华
网站建设 2026/1/20 19:58:38

USB 赋能 + AI 降噪双 buff!这款语音处理模组,让全场景沟通清晰到底

而这款具有 USB 功能的 AI 降噪语音处理模块&#xff0c;正是为解决这些问题而来。它将 USB 免驱便捷性与 AI 智能声学处理技术深度融合&#xff0c;既打破了传统模组的接口适配壁垒&#xff0c;又以硬核性能攻克噪音、回音等行业难题&#xff0c;成为多领域设备升级的 “声学核…

作者头像 李华
网站建设 2026/1/19 5:23:17

RabbitMQ消息堆积问题处理

RabbitMQ消息堆积问题处理-ELK日志使用mq传输 20260115 下午2点 发现rabbitmq消息堆积&#xff0c;看是_log 的消息堆积&#xff0c;应该是ELK出现问题 df -h 查看ELK服务器 /dev/vda1 80G 80G 20K 100% / 需要释放磁盘空间&#xff0c;清理/var/log日志 后恢复至 …

作者头像 李华
网站建设 2026/1/21 10:13:15

昊衡科技 多芯光纤三维形状传感系统,精准感知!

关键词&#xff1a;OFDR &#xff0c;多芯光纤&#xff0c;光纤三维形状传感&#xff0c;三维形变重构&#xff0c;多芯光纤传感方案 对于空间形态感知要求极高的微创手术领域而言&#xff0c;如何精准、实时地监测柔性结构的三维形变&#xff0c;一直是技术落地过程中的关键痛…

作者头像 李华