LeetCode 解题思路 33(Hot 100)

解题思路:

  1. 左边界查找​​:
  • 初始化指针和开始位置 left、right、start。在 left <= right 的条件下循环:
  • 计算中间索引 mid,避免整数溢出(mid = left + (right - left) / 2)。
  • 若中间元素等于目标值,记录当前位置并继续向左半部分搜索。
  • 若中间元素小于目标值,说明目标值在右半部分,更新 left = mid + 1。
  • 若中间元素大于目标值,说明目标值在左半部分,更新 right = mid - 1。
  1. 右边界查找:
  • 初始化指针和结束位置 left、right、end。在 left <= right 的条件下循环:
  • 计算中间索引 mid,避免整数溢出(mid = left + (right - left) / 2)。
  • 若中间元素等于目标值,记录当前位置并继续向右半部分搜索。
  • 若中间元素小于目标值,说明目标值在右半部分,更新 left = mid + 1。
  • 若中间元素大于目标值,说明目标值在左半部分,更新 right = mid - 1。

Java代码:

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int start = binarySearchLeft(nums, target);
        if (start == -1) return new int[]{-1, -1};
        int end = binarySearchRight(nums, target);
        return new int[]{start, end};
    }

    private int binarySearchLeft(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int start = -1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                start = mid;
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return start;
    }

    private int binarySearchRight(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int end = -1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                end = mid;
                left = mid + 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return end;
    }
}

复杂度分析:

  • 时间复杂度: O(logn)。两次二分查找各消耗 O(logn) 时间,总体仍为O(logn)。
  • 空间复杂度: O(1)。仅使用了常数额外空间。

解题思路:

  1. 二分查找​​: 初始化指针 left 和 right,计算中间位置 mid 循环查找。
  2. 检查中点​​: 若 numsmid 等于目标值,直接返回 mid。
  3. 判断左半段是否有序​​: 若 numsleft <= numsmid,说明左半段有序。若目标值在 (numsleft, numsmid) 范围内,则在左半段继续搜索,否则转向右半段。
  4. 判断右半段是否有序​​: 若左半段无序,则右半段必然有序。若目标值在 (numsmid, numsright) 范围内,则在右半段继续搜索,否则转向左半段。

Java代码:

java 复制代码
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[left] <= nums[mid]) {
                if (target >= nums[left] && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else {
                if (target > nums[mid] && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
}

复杂度分析:

  • 时间复杂度: O(log n)。每次二分将搜索范围缩小一半。
  • 空间复杂度: O(1)。仅使用常数额外空间。
相关推荐
computersciencer几秒前
应用贝叶斯公式:迟到了,那坐的是哪种交通工具呢?
算法·机器学习·概率论
若亦_4 分钟前
排序>>交换排序
java·数据结构·算法
dialect_9 小时前
KMP算法
开发语言·c++·算法
reikocao9 小时前
卡尔曼滤波的动态机制:P如何改变融合权重
算法
jktantan9 小时前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
总要学点什么10 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
漂流瓶jz10 小时前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
吞下星星的少年·-·10 小时前
Div.2 CF 1130B题(构造,贪心)
算法·贪心·构造
文丑颜不良啊10 小时前
LeetCode1481~1500题目解析
java·leetcode
前端精髓11 小时前
调用openrouter的免费API模型
java·前端·javascript