二分查找类算法题核心笔记

二分查找类算法题核心笔记(含个人核心疑惑标注)

一、核心公理(底层铁律,解决「left==right何时出现」的疑惑)

【核心疑惑1】:left==right到底什么时候出现?是不是只有区间缩到1个元素时才会出现?

  1. left == right ↔ 二分搜索的有效区间长度为1 (仅含1个元素),无任何例外:
    • 场景1:初始区间就1个元素(如nums=[5],直接left=right=0);
    • 场景2:从多元素区间缩小到1个元素(如nums=[1,3,5,7]缩到left=right=3);
  2. 区间长度≠1时:
    • 长度>1 → left < right(绝对不会出现left==right);
    • 长度=0 → left > right(区间为空,无元素可查);
  3. 二分法的本质:通过「缩小有效区间」逼近答案,核心差异仅在于「是否处理长度为1的区间(即left==right的情况)」。

二、题型核心分类(解决「什么时候用left<right,什么时候用left<=right」的核心疑惑)

【核心疑惑2】:为什么找最小值只用left<right(到leftright就停),找插入位置却要用left<=right(还要处理leftright)?

分类 核心目标 对「left==right(长度1区间)」的处理 循环条件 选择逻辑(解答核心疑惑) 最终答案逻辑
类型A:找边界/定值 找数组中「已存在的元素位置」(最小值/最大值/第一个≥target的元素) 停止处理,直接取该位置为答案 while left < right 答案是数组里"本来就有"的元素位置,缩到长度1区间就确定了答案,无需再处理 循环终止时left==right,返回该位置元素/索引
类型B:推导结果 找插入位置/判断元素是否存在(存在返回True/False) 继续处理,判断后推导最终答案 while left <= right 答案是"推导出来的结果"(插入位置/存在与否),长度1区间只是最后一个待检查的元素,需判断后确定最终答案(比如判断插入到该元素左边还是右边) 循环终止时left > right,返回left(插入位置)/False(不存在)

【之前的关键误区】:曾误以为「找唯一值」是判断标准(比如searchMatrix看似找target位置,就该用left<right),实际纠正:

  • 误区本质:searchMatrix的核心是「推导target是否存在」(类型B),而非「单纯找target位置」,因此仍用left<=right;
  • 插入位置的"唯一性"≠"数组已有元素位置":插入位置是推导的唯一位置(比如nums=[1,3,5],target=4的插入位置2),而非数组里本就有的元素位置,因此需处理left==right。

三、解题三步法(套用到所有二分题,彻底解决循环条件选择疑惑)

步骤1:判断题型类型(核心,解决循环条件选择的根本)

  • 问自己:最终答案是「数组里已有的元素位置」(类型A),还是「推导出来的结果」(类型B)?
    • 类型A(找边界/定值):旋转数组最小值、第一个大于target的元素、峰值位置、最后一个小于target的元素;
    • 类型B(推导结果):插入位置、判断元素是否存在(二维矩阵searchMatrix)、找target索引(不存在返回-1)。

步骤2:确定循环条件(直接对应left==right的处理方式)

【核心疑惑3】:循环条件和left==right的关系?

  • 类型A → while left < right:长度1区间(left==right)时终止,不进入循环处理;
  • 类型B → while left <= right:长度1区间(left==right)时仍满足条件,继续进入循环处理。

步骤3:边界更新(保证区间自洽,避免死循环)

【避坑疑惑】:为什么找最小值时right=mid,找插入位置时right=mid-1?

  • 通用原则:想排除mid → left=mid+1;想保留mid(mid可能是答案)→ right=mid
  • 类型A注意:更新时避免right=mid-1(易漏掉mid这个答案,比如找最小值时mid可能就是最小值);
  • 类型B注意:更新时必须left=mid+1/right=mid-1(排除已检查的mid,否则无法缩小到空区间)。

四、常见避坑点(对应疑惑的易错点)

  1. 区间定义与更新不一致(最易踩坑):
    • while left <= right(闭区间)却更新right=mid → 死循环(left==right时mid不变,边界不更新);
    • while left < right(左闭右开)却初始化right=len(nums)-1 → 漏查元素;
  2. 类型A误用left <= right:长度1区间时进入循环,mid不变导致死循环(比如找最小值时);
  3. 类型B更新时未±1:比如left=mid,导致区间无法缩小到空,死循环;
  4. 混淆「有效区间」:开区间写法中right=len(nums),有效区间是[left, right-1],但核心逻辑仍围绕left==right=长度1区间。

五、经典例题拆解(对应疑惑的实战验证)

例1:类型A(找旋转数组最小值,验证「为什么用left<right」)

【核心疑惑验证】:缩到left==right就确定最小值,无需处理

python 复制代码
def findMin(nums):
    left, right = 0, len(nums)-1
    while left < right:  # 类型A:到left==right就停
        mid = (left+right)//2
        if nums[mid] > nums[right]:
            left = mid + 1  # 排除mid(mid在左半大数组,不可能是最小值)
        else:
            right = mid     # 保留mid(mid可能是最小值,避免漏判)
    return nums[left]  # left==right,直接返回(无需处理)

例2:类型B(找插入位置,验证「为什么用left<=right」)

【核心疑惑验证】:left==right时需处理,判断插入方向

python 复制代码
def searchInsert(nums, target):
    left, right = 0, len(nums)-1
    while left <= right:  # 类型B:left==right时继续处理
        mid = (left+right)//2
        if nums[mid] < target:
            left = mid + 1  # 排除mid,插入位置在右侧
        else:
            right = mid - 1 # 排除mid,插入位置在左侧
    return left  # left>right,返回推导的插入位置

例3:类型B(searchMatrix,验证「看似找位置却用left<=right」)

【误区纠正验证】:核心是推导存在性,而非找位置

python 复制代码
def searchMatrix(matrix, target):
    m,n=len(matrix),len(matrix[0])
    left,right=0,m*n-1
    while left<=right:  # 类型B:推导存在性,需处理left==right
        mid=(left+right)//2
        if matrix[mid//n][mid%n]==target:
            return True  # 找到位置,推导"存在"
        if matrix[mid//n][mid%n]<target:
            left=mid+1
        else:
            right=mid-1
    return False  # left>right,推导"不存在"

六、核心总结(直击所有疑惑的本质)

  1. 二分法的核心不是「区间写法」(闭/开),而是「是否处理长度1的区间(left==right)」;
  2. 类型A(找定值/边界):缩到left==right就停(用left<right),直接取答案;
  3. 类型B(推导结果):处理left==right(用left<=right),推导最终答案;
  4. 所有疑惑的根源:混淆了「答案是数组已有位置」和「答案是推导结果」,抓住这一点就能秒选循环条件。
相关推荐
大模型实验室Lab4AI1 小时前
GDPO:多目标强化学习高效优化新路径
人工智能·深度学习·算法·机器学习
小O的算法实验室2 小时前
2026年CIE SCI2区TOP,用于地质灾害监测的配备自主对接站的无人机多航次路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
仟濹2 小时前
【算法打卡day9(2026-02-14 周六)算法:并查集】 4-卡码网108-冗余连接
算法
hoiii1872 小时前
拉丁超立方抽样(LHS)的MATLAB实现:基本采样与相关采样
开发语言·算法
zhim002 小时前
数据结构笔记(下)
数据结构
不想看见4042 小时前
旋转数组查找数字--力扣101算法题解笔记
数据结构·算法
好学且牛逼的马2 小时前
【Hot100|24-LeetCode 141. 环形链表 - 完整解法详解】
算法·leetcode·链表
yxc_inspire2 小时前
2026年寒假牛客训练赛补题(六)
算法
哈库纳2 小时前
dbVisitor 6.7.0 解读:公元前日期处理的两种方案
后端·算法·架构