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

二分查找的边界问题

前言

二分查找(Binary Search)是一种高效的查找算法,时间复杂度为O(log n)。它适用于已排序的数组或列表。本文将详细介绍二分查找的两种常见写法:闭区间写法和左闭右开区间写法。

一、二分查找基本思想

二分查找的核心思想是"分而治之":

  1. 将查找区间分成两部分
  2. 比较中间元素与目标值
  3. 根据比较结果决定继续在左半部分或右半部分查找
  4. 重复上述过程直到找到目标值或确定目标值不存在

二、闭区间写法 [left, right]

闭区间写法中,查找区间包含左右边界,即[left, right]

代码实现

#include <vector>
using namespace std;int binarySearchClosed(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1; // 闭区间包含右边界while (left <= right) { // 1.注意是<=int mid = left + (right - left) / 2; // 2.防止溢出if (nums[mid] == target) {return mid; // 找到目标} else if (nums[mid] < target) {left = mid + 1; // 3.搜索右半部分} else {right = mid - 1; // 4.搜索左半部分}}return -1; // 未找到
}

关键点说明

  1. 初始化right = len(nums) - 1,因为要包含最后一个元素

  2. 循环条件left <= right,因为当left == right时区间[left, right]仍然有效

  3. 边界更新

    • left = mid + 1:因为nums[mid]已经检查过,可以排除
    • right = mid - 1:同理

三、左闭右开区间写法 [left, right)

左闭右开区间写法中,查找区间包含左边界但不包含右边界,即[left, right)

代码实现

int binarySearchLeftClosed(vector<int>& nums, int target) {int left = 0;int right = nums.size(); // 右边界不包含while (left < right) { // 注意是<int mid = left + (right - left) / 2;if (nums[mid] == target) {return mid;} else if (nums[mid] < target) {left = mid + 1; // 搜索右半部分} else {right = mid; // 注意不是mid-1}}return -1;
}

关键点说明

  1. 初始化right = len(nums),因为右边界不包含

  2. 循环条件left < right,因为当left == right时区间[left, right)无效

  3. 边界更新

    • left = mid + 1:与闭区间相同
    • right = mid:因为右边界不包含,所以不需要mid - 1

四、两种写法的比较

特性闭区间写法左闭右开区间写法
初始化右边界len(nums)-1len(nums)
循环条件left <= rightleft < right
右边界更新right = mid - 1right = mid
区间含义[left, right][left, right)
终止条件left > rightleft == right

五、实际应用中的选择

两种写法都是正确的,选择哪一种主要取决于个人习惯和具体场景:

  1. 闭区间写法

    • 更直观,区间定义明确
    • 边界更新对称(left=mid+1, right=mid-1)
  2. 左闭右开区间写法

    • 右边界初始化更简单(直接使用nums.size)
    • 在某些变种问题中可能更方便

六、例题展示

例题链接:704. 二分查找 - 力扣(LeetCode)
在这里插入图片描述

解答:

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while(left <= right){int mid = (right - left) / 2 + left;int num = nums[mid];if (num == target) {return mid;} else if (num > target) {right = mid - 1;} else {left = mid + 1;}}return -1;}
};

七、常见错误与注意事项

  1. 溢出问题:计算mid时使用left + (right - left) // 2而不是(left + right) // 2,防止left和right很大时相加溢出
  2. 边界更新错误:确保在左闭右开写法中不要错误地使用right = mid - 1
  3. 循环条件混淆:注意两种写法的循环条件不同
  4. 未排序数组:二分查找要求输入数组必须是有序的

八、总结

二分查找是一种高效且常用的算法,掌握其两种区间写法对于解决各种变种问题非常有帮助。理解区间定义和边界更新规则是关键,建议通过大量练习来熟练掌握这两种写法。

希望这篇博客能帮助你更好地理解二分查找算法!在实际编程中,可以根据具体情况和个人偏好选择适合的写法。

相关文章:

  • Python训练营打卡——DAY25(2025.5.14)
  • [论文阅读]Formalizing and Benchmarking Prompt Injection Attacks and Defenses
  • MySQL 学习(九)bin log 与 redo log 的区别有哪些,为什么快速恢复使用 redo log 而不用 bin log?
  • 基于javaweb的SpringBoot高校图书馆座位预约系统设计与实现(源码+文档+部署讲解)
  • 深度强化学习 | 图文详细推导软性演员-评论家SAC算法原理
  • html js 原生实现web组件、web公共组件、template模版插槽
  • Go 语言 sqlx 库使用:对 MySQL 增删改查
  • 破解商业综合体清洁管理困局:商业空间AI智能保洁管理系统全场景解决方案
  • 知识图谱重构电商搜索:下一代AI搜索引擎的底层逻辑
  • Flink CDC—实时数据集成框架
  • 【论文笔记】ViT-CoMer
  • CCF第七届AIOps国际挑战赛季军分享(RAG)
  • HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南
  • 【HCIA】BFD
  • linux内核主要由哪五个模块构成?
  • 网络协议分析 实验七 FTP、HTTP、DHCP
  • Linux相关概念和易错知识点(39)(URL、HTTP)
  • MK米客方德SD NAND:无人机存储的高效解决方案
  • HTTP 连接复用机制详解
  • 【KWDB 创作者计划】MySQL数据库迁移至KWDB的完整实践指南
  • 七部门:进一步增强资本市场对于科技创新企业的支持力度
  • 白玉兰奖征片综述丨动画的IP生命力
  • 沙青青评《通勤梦魇》︱“人机组合”的通勤之路
  • 中美发布日内瓦经贸会谈联合声明达成关税共识,外交部回应
  • 上海建筑领域绿色发展2025年工作要点发布
  • 王毅同印度国家安全顾问多瓦尔通电话