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

news2024/10/12 19:51:00

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

主要思路:

  1. 使用两次二分查找

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

代码解析:

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,如果找不到目标元素,返回 -1
        int 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,如果找不到目标元素,返回 -1
        int 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.coloradmin.cn/o/2208649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《OpenCV计算机视觉》—— 人脸识别

识别图片如下&#xff1a; 完整代码&#xff1a; import cv2image cv2.imread(face.png) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) """ 加载分类器 """ faceCascade cv2.CascadeClassifier(haarcascade_frontalface_default.xml) &…

UE5 使用Animation Budget Allocator优化角色动画性能

Animation Budget Allocator是UE内置插件&#xff0c;通过锁定动画系统所占CPU的预算&#xff0c;在到达预算计算量时对动画进行限制与优化。 开启Animation Budget Allocator需要让蒙皮Mesh使用特定的组件&#xff0c;并进行一些编辑器设置即可开启。 1.开启Animation Budget…

浏览器指纹原理及技术实现探索

文章目录 [TOC](文章目录) 前言一、什么是浏览器指纹&#xff1f;二、浏览器指纹的作用三、 浏览器指纹如何保证唯一性四、浏览器指纹的隐私问题五、如何应对浏览器指纹&#xff1f;六、目前常用的技术方案七、技术实现探索1、简易方式2、fingerprintjs2方式 八、总结 前言 在…

国家药包材标准数据库在线查询方法<实用篇>

从业于医药相关的包材行业这么多年&#xff0c;对于许多医药行业的生产企业、药品检验机构、药品注册申请人以及医疗机构的朋友而言&#xff0c;查询国家药包材标准是他们日常工作的一部分&#xff0c;相对容易。然而&#xff0c;对于那些刚进入这个行业的新手或者普通大众来说…

【测试】自动化——常用函数

元素的定位 查找元素&#xff1a;find_element(方式&#xff0c;“元素”)&#xff0c;表示查找一个元素&#xff1b; find_element(方式&#xff0c;“元素”)&#xff0c;表示查找多个元素。 ###使用查找多个元素 ChromeInsChromeDriverManager().install() driverwebdriv…

uniapp学习(005-2 详解Part.2)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第41p-第p51的内容 文章目录 mainifest.json文件配置获取微信小程序appid注册微信小程序微信小程序控制台图形界…

Linux 命令:每日一学,文件查找之find命令实践

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 0x00 前言简述 描述&#xff1a;前面我们一些学习了Linux文件内容查看、分隔列、排序、统计等命令&#xff0c;相信认真学习实践过的看友都已经初步掌握了吧&#xff0c;今天我们继续学习下Linux中…

本地生活服务项目入局方案解析!本地生活服务商系统能实现怎样的作业效果?

当前&#xff0c;各大平台的本地生活服务业务日渐兴盛&#xff0c;提高创业者入局意向的同时&#xff0c;也让本地生活服务项目有哪些等问题也成为了多个创业者社群中的热议对象。而从目前的讨论情况来看&#xff0c;在创业者们所询问的众多本地生活服务项目中&#xff0c;通过…

从二维到三维,电商行业有哪些变化?

从二维到三维&#xff0c;电商行业经历了一系列显著的变化&#xff0c;这些变化不仅体现在商品展示的方式上&#xff0c;还深刻影响了消费者的购物体验、电商平台的运营策略以及整个电商行业的竞争格局。 一、商品展示方式的变革 二维展示阶段&#xff1a; 在电商行业的早期&…

一键安装与配置Stable Diffusion,轻松实现AI绘画

随着技术的迭代&#xff0c;目前 Stable Diffusion 已经能够生成非常艺术化的图片了&#xff0c;完全有赶超人类的架势&#xff0c;已经有不少工作被这类服务替代&#xff0c;比如制作一个 logo 图片&#xff0c;画一张虚拟老婆照片&#xff0c;画质堪比相机。 最新 Stable Di…

kubernetes(K8s)学习(一)

本文主要是搭建一个k8s平台&#xff0c;并部署一个springboot的jar包&#xff0c;后续以此作为学习k8s的环境。 1. 搭建k8s集群 网上有很多指导&#xff0c;大家可以在网上搜索一下&#xff0c;比如这个&#xff1a;K8s搭建集群-CSDN博客&#xff0c;本人通过VMware安装3台虚拟…

国外电商系统开发-运维系统操作脚本

查看脚本内容&#xff0c;只需要点击即可&#xff1a; 执行脚本&#xff0c;请点击 点击了下一步后&#xff0c;可以输出脚本参数&#xff0c;当然你可以可以不输入&#xff0c;直接下一步就行&#xff1a; 现在&#xff0c;点击【下一步】执行开始出初始化脚本&#xff1a; …

【力扣刷题实战】(归并排序)合并两个有序数组

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 力扣题目&#xff1a; 合并两个有序数组 题目描述 示例 1&#xff1a; 示例 2&#xff1a; 示例 3&#xff1a; 解题思路 具体思路 题目要点 作图助解 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#…

Linux多任务编程(网络编程-数据库篇)

前言 本文记录嵌入式领域用的小型数据库 sqlite数据库&#xff0c;以及c语言中使用sqlite3。 数据库 数据存储方式&#xff08;3种&#xff09; &#xff08;1&#xff09;直接地址存储&#xff1a;单片机的烧写&#xff1b; &#xff08;2&#xff09;文件存储&…

接口多继承与子类继承多接口时的冲突问题,方法冲突与变量冲突.....

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

IDEA2024最新版本运行Web应用时 Tomcat 日志中的中文乱码问题修复解决

一、IDEA2024运行Tomcat日志中的中文乱码问题修复 在使用tomcat的时候经常遇到乱码问题&#xff0c;要么是控制台输出乱码或者输出日志乱码&#xff0c;要么页面接收乱码&#xff0c;产生乱码的根本原因就是编码和解码不一致。网上有的文章写得也有问题&#xff0c;今天自己多看…

计算机毕业设计 | springboot商城售后管理系统 购物平台(附源码)

1&#xff0c;绪论 1.1 开发背景 在数字化时代的推动下&#xff0c;产品售后服务管理机构面临着信息化和网络化的挑战。传统的手工管理和纸质档案已经无法满足管理人员和读者的需求。为了提高产品售后服务管理机构的管理效率和服务质量&#xff0c;开发和实现一个基于Java的售…

轻量服务器和云服务器ecs哪个好用一些?

轻量服务器和云服务器ecs哪个好用一些&#xff1f;轻量服务器与云服务器ECS在多方面存在显著差异&#xff0c;对于需要高性能计算和大规模数据处理的用户来说&#xff0c;ECS可能是更好的选择&#xff1b;而对于预算有限且需求较为简单的用户来说&#xff0c;轻量服务器可能更为…

计算机网络:数据链路层 —— 可靠传输服务

文章目录 可靠传输停止-等待 (SW) 协议超时重传机制分组编号机制ACK 丢失问题ACK 延迟问题 注意事项信道利用率 回退 N 帧 (GBN) 协议滑动窗口信道利用率无传输差错超时重传、回退N帧 累计确认 选择重传 (SR) 协议滑动窗口 可靠传输 若数据链路层向其上层提供的服务类型为可靠…

【Linux】Screen的使用:新建、退出、再登陆

Linux screen 命令详解与使用指南 在Linux系统中&#xff0c;screen 是允许用户在单个终端会话中运行多个进程&#xff0c;并能在会话之间切换。 适用情况&#xff1a;screen 特别适用于远程登录&#xff08;如通过SSH&#xff09;时&#xff0c;确保即使网络连接断开&#x…