Leetcode 在排序数组中查找元素的第一个和最后一个位置

devtools/2024/10/19 2:53:10/

在这里插入图片描述
这段代码的目的是在一个有序的数组中查找目标元素的第一个和最后一个位置。如果目标元素不存在,返回 [-1, -1]算法要求时间复杂度为 O(log n),所以使用了二分查找的思想。

主要思路:

  1. 使用两次二分查找

    • 第一次二分查找用于找到目标元素的第一个位置
    • 第二次二分查找用于找到目标元素的最后一个位置
  2. 在二分查找的过程中,通过调整搜索范围(即移动 startend 指针),分别定位目标元素的首次和末次出现的位置。

代码解析:

java">class Solution {public int[] searchRange(int[] nums, int target) {int[] result = {-1, -1};  // 初始化结果数组,默认值为 [-1, -1]result[0] = findFirst(nums, target);  // 找到目标的第一个位置result[1] = findLast(nums, target);   // 找到目标的最后一个位置return result;  // 返回结果}// 二分查找找到第一个出现的位置private int findFirst(int[] nums, int target) {int index = -1;  // 初始化index为 -1,如果找不到目标元素,返回 -1int start = 0, end = nums.length - 1;while (start <= end) {int mid = start + (end - start) / 2;  // 计算中间位置,避免整数溢出if (nums[mid] >= target) {  // 如果中间元素大于或等于目标,缩小范围到左半部分end = mid - 1;} else {  // 如果中间元素小于目标,缩小范围到右半部分start = mid + 1;}if (nums[mid] == target) {  // 当找到目标元素时,记录下当前位置index = mid;}}return index;  // 返回找到的第一个位置,如果没找到,返回 -1}// 二分查找找到最后一个出现的位置private int findLast(int[] nums, int target) {int index = -1;  // 初始化index为 -1,如果找不到目标元素,返回 -1int start = 0, end = nums.length - 1;while (start <= end) {int mid = start + (end - start) / 2;  // 计算中间位置if (nums[mid] <= target) {  // 如果中间元素小于或等于目标,缩小范围到右半部分start = mid + 1;} else {  // 如果中间元素大于目标,缩小范围到左半部分end = mid - 1;}if (nums[mid] == target) {  // 当找到目标元素时,记录下当前位置index = mid;}}return index;  // 返回找到的最后一个位置,如果没找到,返回 -1}
}

算法思想:

  1. 二分查找的思想

    • 在一个有序数组中查找目标值,二分查找可以通过每次将搜索范围减半,从而达到 O(log n) 的时间复杂度。
    • 这里我们分别实现了两次二分查找:
      • 第一次查找目标值的第一个位置:每次找到目标值后,继续向左搜索,直到找到第一个出现的位置。
      • 第二次查找目标值的最后一个位置:每次找到目标值后,继续向右搜索,直到找到最后一个出现的位置。
  2. 边界控制

    • 每次查找到目标值时,并不立即停止,而是继续缩小搜索范围以确保找到第一个或最后一个出现的目标值。
    • 如果数组中不存在目标值,两个函数会返回默认的 -1,表示没有找到目标值。

时间复杂度:

  • 每次二分查找的时间复杂度是 O(log n),因为在每次循环中,我们将搜索范围缩小了一半。
  • 两次二分查找的总时间复杂度是 O(2 * log n) ≈ O(log n)。

通过这种方法,我们能够在高效的时间内找到目标值的第一个和最后一个位置。

算法核心要点

算法中确实有两个核心要点:

1. nums[mid]target 的大小判断使用的是大于等于 (>=) 或小于等于 (<=)

  • findFirst 方法中,使用 >= 确保当找到目标值后,继续向左查找以找到目标值的最左位置。即便找到了目标值,也不会立即停止搜索,而是继续检查是否存在更左边的目标值。
  • findLast 方法中,使用 <= 确保当找到目标值后,继续向右查找以找到目标值的最右位置。同样地,即便找到了目标值,也不会立即返回,而是继续搜索右边,确保找到了最右边的目标值。

2. if (nums[mid] == target) 会多次更新 index

  • nums[mid] == target 时,我们会更新 index,但不会立即返回 index,而是继续调整搜索范围,查找目标值的更左或更右边界。
  • findFirst 中,index 可能会多次被更新,直到找到最左边的目标值位置。
  • findLast 中,index 同样会多次被更新,直到找到最右边的目标值位置。

总结:

  • 大于等于/小于等于的判断:确保查找过程中不会错过目标值的边界(最左或最右位置)。
  • 多次更新 index:在找到目标值时,并不会立即返回,而是继续更新,以确保最终返回的 index 是符合要求的最左或最右位置。

这两个核心点共同确保了算法能够高效地找到数组中目标值的第一个和最后一个位置,并且时间复杂度为 O(log n)。


http://www.ppmy.cn/devtools/125117.html

相关文章

解决雪花ID在前端精度丢失问题

解决雪花ID在前端精度丢失问题 在现代分布式系统中&#xff0c;雪花算法&#xff08;Snowflake&#xff09;被广泛用于生成唯一的ID。这些ID通常是Long类型的整数。然而&#xff0c;当这些ID从后端传递到前端时&#xff0c;JavaScript的精度限制可能会导致精度丢失&#xff0c…

计算机等级考试——二级MSOffice高级应用考试常用函数

二级MSOffice高级应用考试常用函数 使用说明&#xff1a;本文共介绍了在二级 MSOffice 高级应用考试过程中考到的 6 类共 51 个函数&#xff0c;在学习过程建议打开Excel 工作表【公式】-【函数库】&#xff0c;边操作边学习&#xff0c;更易于理解中每个函数参数意义。 一、 …

教程:宏基因组数据分析教程

Orchestrating Microbiome Analysis Orchestrating Microbiome Analysis是一套包含宏基因组各种数据分析的教程&#xff0c;非常安利大家学习。 16S-analysis 16S-analysis是一本用于扩增子16s等微生物数据分析的教程&#xff0c;很适合新手入门学习。 Introduction to micro…

vue跨标签页通信(或跨窗口)详细教程

在 Vue 应用中,跨标签页(或跨窗口)的通信通常涉及到两个或多个浏览器标签页之间的信息共享。由于每个标签页或窗口都是独立的 JavaScript 执行环境,它们不能直接通过 Vue 或其他 JavaScript 库来直接相互通信。但是,有一些方法可以实现这种跨标签页的通信,主要依靠浏览器…

QD1-P5 HTML 段落标签(p)换行标签(br)

本节视频 www.bilibili.com/video/BV1n64y1U7oj?p5 ‍ 本节学习 HTML 标签&#xff1a; p标签 段落br标签 换行 ‍ 一、p 标签-段落 1.1 使用 p 标签划分段落 <p>段落文本</p>示例 <!DOCTYPE html> <html><head><meta charset"…

Facebook脸书投放目录guanggao(更适合独立站)操作步骤教学

Facebook guanggao是企业进行品牌推广、产品销售和营销转化的有效工具。在Facebook guanggao中创建目录可以帮助企业更好地展示产品&#xff0c;提高guanggao效果。以下是创建目录的详细步骤&#xff1a; 登录Facebook Business Manager&#xff08;BM业务管理器&#xff09;&a…

医疗病历交互系统:Spring Boot技术解析

第4章 系统设计 4.1 系统总体设计 系统不仅要求功能完善&#xff0c;而且还要界面友好&#xff0c;因此&#xff0c;对于一个成功的系统设计&#xff0c;功能模块的设计是关键。由于本系统可执行的是一般性质的学习信息管理工作&#xff0c;本系统具有一般适用性&#xff0c;其…

UniApp 与微信小程序详细对比

UniApp 与微信小程序详细对比 1. 开发环境 微信小程序&#xff1a; 主要使用微信开发者工具提供模拟器、调试工具和性能监控只能开发微信小程序 UniApp&#xff1a; 主要使用 HBuilderX&#xff0c;但也支持 VS Code 等其他编辑器HBuilderX 提供可视化界面、代码提示、调试工…