【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;
    }
}
相关推荐
历程里程碑2 分钟前
普通数组-----除了自身以外数组的乘积
大数据·javascript·python·算法·elasticsearch·搜索引擎·flask
4311媒体网4 分钟前
C语言操作符全解析 C语言操作符详解
java·c语言·jvm
静听山水4 分钟前
Redis核心数据结构-list
数据结构·redis·list
淡忘_cx5 分钟前
使用Jenkins自动化部署spring-java项目+宝塔重启项目命令(2.528.2版本)
java·自动化·jenkins
AI视觉网奇5 分钟前
blender 导入fbx 黑色骨骼
学习·算法·ue5·blender
星火开发设计6 分钟前
this 指针:指向对象自身的隐含指针
开发语言·数据结构·c++·学习·指针·知识
毕设源码-钟学长9 分钟前
【开题答辩全过程】以 基于SSM的孤儿救助信息管理系统设计与实现为例,包含答辩的问题和答案
java
weixin_468466859 分钟前
目标识别精度指标与IoU及置信度关系辨析
人工智能·深度学习·算法·yolo·图像识别·目标识别·调参
独自破碎E9 分钟前
【曼哈顿距离】BISHI25 最大 FST 距离
java·开发语言
苏涵.9 分钟前
Java三大集合:List、Set、Map
java·开发语言