【LeetCode精选算法】二分查找专题一

目录

1.二分查找

题目链接

详细解题思路

Java代码实现

2.在排序数组中查找元素的第一个和最后一个位置

题目链接

详细解题思路

Java代码实现

3.搜索插入位置

题目链接

详细解题思路

Java代码实现

4.x的平方根

题目链接

详细解题思路


1.二分查找

题目链接

704. 二分查找 - LeetCode

详细解题思路

  1. 初始化搜索区间 :使用两个指针 leftright 分别指向数组的起始索引 0 和末尾索引 nums.length - 1,表示当前搜索区间为 [left, right]

  2. 循环条件 :当 left <= right 时,说明区间内还有元素待搜索。

  3. 计算中间位置 :为了避免整数溢出,使用 mid = left + (right - left) / 2 计算中间索引。

  4. 判断与目标值的关系

    • 如果 nums[mid] == target,直接返回 mid

    • 如果 nums[mid] > target,说明目标值在左半部分,将 right 更新为 mid - 1,缩小区间至左半部分。

    • 如果 nums[mid] < target,说明目标值在右半部分,将 left 更新为 mid + 1,缩小区间至右半部分。

  5. 循环结束 :当 left > right 时,说明整个区间内没有目标值,返回 -1

Java代码实现

java 复制代码
class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

2.在排序数组中查找元素的第一个和最后一个位置

题目链接

34. 在排序数组中查找元素的第一个和最后一个位置 - LeetCode

详细解题思路

  1. 处理边界情况 :如果数组为空,直接返回 [-1, -1]

  2. 寻找左边界

    • 使用二分查找,当 nums[mid] < target 时,说明目标值在右半部分,将 left 更新为 mid + 1

    • 否则(即 nums[mid] >= target),说明目标值在左半部分或当前位置就是左边界,将 right 更新为 mid,继续在左半部分搜索。

    • 循环结束后,leftright 指向的位置可能是左边界,需要检查该位置的值是否等于 target,若不等于则说明目标值不存在,返回 [-1, -1]

  3. 寻找右边界

    • 在找到左边界的基础上,重置 left 为当前左边界位置(或 0),right 为数组末尾。

    • 使用二分查找,当 nums[mid] <= target 时,说明目标值在右半部分或当前位置就是右边界,将 left 更新为 mid

    • 否则(即 nums[mid] > target),说明目标值在左半部分,将 right 更新为 mid - 1

    • 注意:在计算 mid 时,为了避免死循环,需要向上取整,即 mid = left + (right - left + 1) / 2

  4. 返回结果:左边界和右边界分别记录在结果数组中返回。

Java代码实现

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] result = {-1, -1};
        if (nums.length == 0) return result;

        // 寻找左边界
        int left = 0, right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        if (nums[left] != target) return result;
        result[0] = left;

        // 寻找右边界
        right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left + 1) / 2; // 向上取整
            if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid;
            }
        }
        result[1] = right;
        return result;
    }
}

3.搜索插入位置

题目链接

35. 搜索插入位置 - LeetCode

详细解题思路

  1. 初始化区间 :设置 left = 0right = nums.length - 1

  2. 二分查找

    • left < right 时,计算 mid = left + (right - left) / 2

    • 如果 nums[mid] < target,说明插入位置在 mid 右侧,将 left 更新为 mid + 1

    • 否则(即 nums[mid] >= target),说明插入位置可能是 mid 或在 mid 左侧,将 right 更新为 mid

  3. 循环结束 :当 left == right 时,循环终止,此时 leftright 即为可能的插入位置。

  4. 最终判断 :检查 nums[right]target 的大小关系:

    • 如果 nums[right] < target,说明目标值应插入到数组末尾,返回 right + 1

    • 否则,返回 right(因为 nums[right] >= target,插入位置即为 right)。

Java代码实现

java 复制代码
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        // 如果目标值大于所有元素,插入到末尾
        if (nums[right] < target) {
            return right + 1;
        }
        return right;
    }
}

4.x的平方根

题目链接

69. x 的平方根 - LeetCode

详细解题思路

  1. 处理特殊情况 :如果 x < 1,直接返回 0(因为非负整数的平方根至少为0,且题目要求整数部分)。

  2. 初始化区间 :平方根的整数部分一定在 [1, x] 之间,设置 left = 1right = x

  3. 二分查找

    • left < right 时,计算 mid = left + (right - left + 1) / 2(向上取整,避免死循环)。

    • 比较 mid * midx 的大小关系:

      • 如果 mid * mid <= x,说明 mid 可能是平方根的整数部分,将 left 更新为 mid

      • 否则(即 mid * mid > x),说明 mid 太大,将 right 更新为 mid - 1

    • 注意 :为了防止 mid * mid 溢出,使用 long 类型存储乘法结果。

  4. 循环结束 :当 left == right 时,循环终止,此时 leftright 即为平方根的整数部分。

java 复制代码
class Solution {
    public int mySqrt(int x) {
        if (x < 1) return 0;
        long left = 1, right = x;
        while (left < right) {
            long mid = left + (right - left + 1) / 2;
            if (mid * mid <= x) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }
        return (int) left;
    }
}
相关推荐
To_OC1 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
2401_841495642 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
爱刷碗的苏泓舒6 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19947 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端