【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;
    }
}
相关推荐
草履虫建模10 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq12 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq12 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
qq_2975746712 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚12 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学13 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang2015092813 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚13 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq13 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
缘空如是13 小时前
基础工具包之JSON 工厂类
java·json·json切换