【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 小时前
豆包大模型在药物研发中的知识检索效率如何?
java·开发语言·数据库
BlockChain8882 小时前
Web3 后端面试专用版
java·面试·职场和发展·go·web3
BlockChain8882 小时前
30+ 技术人转型 Web3 / AI
java·人工智能·go·web3
刘某某.2 小时前
大模型数据传输3 种方式对比
算法
Kratzdisteln2 小时前
【1902】0120-3 Dify变量引用只能引用一层
android·java·javascript
wen__xvn2 小时前
基础算法集训第03天:递推
算法
秋刀鱼程序编程2 小时前
Java基础入门(七)---异常处理
java·开发语言·python
wen__xvn2 小时前
算法基础集训第19天:广度优先搜索
算法·宽度优先
遇见你的雩风2 小时前
Java---多线程(一)
java·开发语言