当前位置: 首页 > news >正文

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代码:

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. 检查中点​​: 若 nums[mid] 等于目标值,直接返回 mid。
  3. 判断左半段是否有序​​: 若 nums[left] <= nums[mid],说明左半段有序。若目标值在 (nums[left], nums[mid]) 范围内,则在左半段继续搜索,否则转向右半段。
  4. 判断右半段是否有序​​: 若左半段无序,则右半段必然有序。若目标值在 (nums[mid], nums[right]) 范围内,则在右半段继续搜索,否则转向左半段。

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)。仅使用常数额外空间。

相关文章:

  • Spring集成asyncTool:实现复杂任务的优雅编排与高效执行
  • 学习需要回看笔记
  • C语言 数据结构【双向链表】动态模拟实现
  • 11. grafana的table表使用
  • [随记] 安装 docker 报错排查
  • Docker 入门指南:基础知识解析
  • 【C++初学】C++实现通讯录管理系统:从零开始的详细教程
  • 道路坑洼目标检测数据集-665-labelme
  • Linux系统学习Day1——虚拟机间的讲话
  • 五子棋游戏开发:静态资源的重要性与设计思路
  • WPF 资源加载问题:真是 XAML 的锅吗?
  • [MySQL数据库] InnoDB存储引擎(二) : 磁盘结构详解
  • 智慧景区能源管理解决方案,为旅游“升温”保驾护航
  • 不用第三方库调用DeepSeek
  • Go语言从零构建SQL数据库(6) - sql解析器(番外)- *号的处理
  • React 列表渲染
  • 算法(0)-时间复杂度-二分法的详解与扩展-对数器-C++版
  • cmake阅读笔记
  • HTTP代理:内容分发战场上的「隐形指挥官」
  • Lettuce与Springboot集成使用
  • 做网站排名大概要多少钱/如何创建网址
  • app制作器软件下载/seo搜索引擎优化介绍
  • 东莞百度代做网站联系方式/品牌策划公司哪家好
  • 免费网站建设模版下载/四种基本营销模式
  • 南宁信息建设网站/关键词排名怎么做上首页
  • 建设厅/西安网站建设方案优化