算法18,二分查找

二分查找核心知识点梳理

一、算法原理

二分查找基于有序数组 的特性,利用「二段性」缩小目标范围:对于当前区间 [left, right],取中间位置 mid,通过比较 nums[mid]与目标值 target的大小,确定 target所在子区间,重复此过程直到找到目标或区间无效。

二、通用模板(朴素版)

以「左闭右闭区间 [left, right]」为例(区间内所有下标都有效),模板代码如下:

复制代码
public int search(int[] nums, int target) {
    int left = 0;
    int right = nums.length - 1; // 右闭区间,初始右边界为数组长度-1
    while (left <= right) {      // 区间有效时持续缩小范围(left==right时仍需检查)
        int mid = left + (right - left) / 2; // 防止(left+right)溢出的mid计算方式
        if (nums[mid] < target) {
            // target在右半段,调整左边界排除左半段
            left = mid + 1;
        } else if (nums[mid] > target) {
            // target在左半段,调整右边界排除右半段
            right = mid - 1;
        } else {
            // 找到目标,返回对应下标
            return mid;
        }
    }
    // 循环结束后仍未找到,返回-1
    return -1;
}
三、关键细节解析
  1. 循环结束条件

    • 若采用「左闭右闭」区间(right = nums.length - 1),循环条件为 left <= right(保证 left == right时仍检查中间元素)。

    • 若采用「左闭右开」区间(right = nums.length),循环条件为 left < right(此时 right初始越界,区间内有效下标为 [left, right))。

  2. mid 计算防溢出

    直接写 (left + right) / 2可能因 left + right超过整数范围(如 leftright极大时)导致溢出。改用 left + (right - left) / 2可避免此问题。

  3. 边界调整逻辑

    • nums[mid] < target时,target一定在 mid右侧,因此左边界调整为 mid + 1(排除 mid及左侧元素)。

    • nums[mid] > target时,target一定在 mid左侧,因此右边界调整为 mid - 1(排除 mid及右侧元素)。

    • nums[mid] == target,直接返回 mid(已找到目标)。

四、示例演示(以有序数组查找为例)

假设数组 nums = [1, 3, 5, 7, 9],目标 target = 5

  • 初始 left=0, right=4,计算 mid = 0 + (4-0)/2 = 2nums[2]=5等于 target,直接返回 2

若目标 target = 2

  • 第一轮:left=0, right=4, mid=2nums[2]=5 > 2right=1(缩小到左半段 [0,1])。

  • 第二轮:left=0, right=1, mid=0nums[0]=1 < 2left=1(缩小到右半段 [1,1])。

  • 第三轮:left=1, right=1, mid=1nums[1]=3 > 2right=0(区间失效)。

  • 循环结束(left > right),返回 -1

通过以上步骤,可系统掌握二分查找的核心逻辑、代码实现及易错点,确保在有序数组查找场景中高效且正确地应用该算法。

相关推荐
JieE21214 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
nanxun88618 小时前
记一次诡异的 Docker 容器"串包"故障排查
java
用户15630681035121 小时前
Day01 | Java 基础(Java SE)
java
行者全栈架构师1 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师1 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_01 天前
mac(m5)平台编译openjdk
java
JieE2122 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
唐青枫2 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java