34. 在排序数组中查找元素的第一个和最后一个位置(中等)

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

  • 1. 题目描述
  • 2.详细题解
    • (1)朴素二分查找算法
    • (2)改进二分查找算法
  • 3.代码实现
    • 3.1 Python
      •   方法一:
      •   方法二:
      •   方法三:优化方法二
    • 3.2 Java

1. 题目描述

题目中转:34. 在排序数组中查找元素的第一个和最后一个位置
在这里插入图片描述
在这里插入图片描述

2.详细题解

(1)朴素二分查找算法

    在非递减(升序)数组中查找目标值的起始和结束位置,如果不存在则返回[-1,-1],最直观和直接的方法是依次遍历,第一次寻找到的位置为起始位置,记录下状态,当数组已遍历完或者遍历到非目标值时,此时上一个位置即为结束位置,时间复杂度为 O ( n ) O(n) O(n),该方法未利用数组有序的条件,典型的二分查找算法,但有一定的变型。
  朴素的二分查找算法,使用传统意义的算法,但当中间值等于目标值时,此时再分别向左和向右扩展,即可找到起始位置和结束位置。此时,最坏情况下的时间复杂度仍然为 O ( n ) O(n) O(n),例如全为目标值组成的数列,如[7,7,7,7,7,7,7],此时仍然要遍历全数组,且还多了二分查找的时间。具体代码实现见Python实现方法一。

(2)改进二分查找算法

  同69. x 的平方根(简单)类似,本质上均属于相同类型的二分查找变型题,在69. x 的平方根(简单)中,寻找算术平方根的整数部分,因此相当于寻找首次大于指定数的整数,该整数减 1 1 1即为所求值,即右指针值。
  针对本题,对于目标值的起始位置和结束位置,可以分别使用二分查找算法寻找。

  • 对于结束位置,寻找最后一个目标值的索引,相当于寻找首次大于目标值的索引,减 1 1 1即可,此时同69. x 的平方根(简单)一致,右指针当中间值大于目标值即会更新为 r i g h t = m i d − 1 right=mid-1 right=mid1,即 r i g h t right right指针完整的记录下来了最后一个目标值的索引。(满足大于目标值才会更新right的值,因此最终right保留的为最后一次大于目标值的中间值,该中间值即为首次大于目标值的索引,而 r i g h t = m i d − 1 right=mid-1 right=mid1,即 r i g h t right right指针为结束位置。

  • 对于起始位置,寻找第一个目标值的索引,相当于寻找在目标值出现之前,最后一个不为目标值的索引,加 1 1 1即可,稍微改变下寻找结束位置索引时的寻找条件,因为需要寻找第一个目标值出现前一个位置的索引,那么当中间值大于等于时即更新 r i g h t = m i d − 1 right=mid-1 right=mid1,此时 r i g h t right right指针完整的记录下来了在目标值出现之前,最后一个不为目标值的索引,此时加 1 1 1即为起始位置的索引。(满足大于等于目标值才会更新 r i g h t right right值 ,故 r i g h t right right记录的是最后一个大于等于目标值的索引,而 r i g h t right right有减1,因此加1即为起始位置。

  • 需要注意的时, r i g h t right right指针记录的不一定是真实的目标值的起始或结束位置的索引,当未找到目标值的时候,程序循环也会结束,因为需要判断找到的起始或者结束位置是否在索引范围内,或者是否目标值,否则返回-1。

  具体代码实现见Python实现方法二。但需要注意的时,此时二分查找起始和结束位置代码冗余度过高,因此可以进一步优化降低代码冗余度,具体代码实现见Python实现方法三。
  Java代码实现直接给出最终优化后算法的实现,见Java实现。

3.代码实现

3.1 Python

  方法一:

class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:l, r = -1, -1left, right = 0, len(nums) - 1while left <= right:mid = (left + right) // 2if nums[mid] == target:l, r = mid, midwhile l - 1 >= 0 and nums[l-1] == target:l -= 1while r + 1 < len(nums) and nums[r+1] == target:r += 1breakelif nums[mid] > target:right = mid - 1else:left = mid + 1return [l, r]

在这里插入图片描述

  方法二:

class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:def binaeySearchRight(nums, target):left, right = 0, len(nums) -1while left <= right:mid = (left + right) // 2if nums[mid] > target:right = mid - 1else:left = mid + 1if right < 0 or nums[right] != target:right = -1return rightdef binaeySearchLeft(nums, target):left, right = 0, len(nums) - 1while left <= right:mid = (left +right) // 2if nums[mid] >= target:right = mid - 1else:left = mid + 1right += 1if right >= len(nums) or nums[right] != target:right = -1return rightleft = binaeySearchLeft(nums, target)right = binaeySearchRight(nums, target)return [left, right]

在这里插入图片描述

  方法三:优化方法二

class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:def binaeySearch(nums, target, direction=True):# 规定:True表示查找起始位置,否则查找结束位置left, right = 0, len(nums) - 1while left <= right:mid = (left + right) // 2if nums[mid] > target or (direction and nums[mid] >= target):right = mid - 1else:left = mid + 1if direction:right += 1if right < 0 or right >= len(nums) or nums[right] != target:right = -1return rightleft = binaeySearch(nums, target, True)right = binaeySearch(nums, target, False)return [left, right]

在这里插入图片描述

3.2 Java

class Solution {public int[] searchRange(int[] nums, int target) {int left = binarySearch(nums, target, true);int right = binarySearch(nums, target, false);return new int[]{left, right};}public int binarySearch(int[] nums, int target, boolean direction){//规定:True表示查找起始位置,否则查找结束位置int left = 0, right = nums.length - 1;while (left <= right){int mid = (left + right) / 2;if (nums[mid] > target || (direction && nums[mid] >= target)){right = mid - 1;}else{left = mid + 1;}}if (direction){right++;}if (right < 0 || right >= nums.length || nums[right] != target){right=-1;}return right;}
}

在这里插入图片描述

  执行用时不必过于纠结,对比可以发现,对于python和java完全相同的编写,java的时间一般是优于python的;至于编写的代码的执行用时击败多少对手,执行用时和网络环境、当前提交代码人数等均有关系,可以尝试完全相同的代码多次执行用时也不是完全相同,只要确保自己代码的算法时间复杂度满足相应要求即可,也可以通过点击分布图查看其它coder的code。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/38829.shtml

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

相关文章

Elasticsearch:Painless scripting 语言(二)

这是继上一篇文章 “Elasticsearch&#xff1a;Painless scripting 语言&#xff08;一&#xff09;” 的续篇。 使用 field API 访问文档中的字段 警告&#xff1a;Field API 仍在开发中&#xff0c;应视为测试版功能。API 可能会发生变化&#xff0c;此迭代可能不是最终状态。…

53、Flink 测试工具测试用户自定义函数详解

1.测试用户自定义函数 a&#xff09;单元测试无状态、无时间限制的 UDF 示例&#xff1a;无状态的 MapFunction 。 public class IncrementMapFunction implements MapFunction<Long, Long> {Overridepublic Long map(Long record) throws Exception {return record …

Ubuntu20.04 安装 cudatookit 12.2 + cudnn 安装

最简约的部署Ubuntu20.04深度学习环境的教程 1. 安装Ubuntu20.04 系统 B站详细的安装教程 简约安装版 2. 安装Nvidia显卡驱动 我参考了各种资料&#xff0c;重装系统&#xff0c;完美解决开机显示器黑屏无法进入桌面的情况 黑屏问题主要是由linux内核更新导致&#xff0c;…

煤矿ar远程协作平台系统提升了操作的安全性和效率

工业AR远程专家协助系统为企业量身打造大型设施的虚拟布局方案。借助先进的AR增强现实技术&#xff0c;企业能够在虚拟环境中精准模拟并购买适配设备&#xff0c;确保设施的顺畅运行。同时&#xff0c;工业AR远程专家协助系统能提供的协作功能让团队成员能够实时共享虚拟布局&a…

昇思25天学习打卡营第8天|MindSpore-SSD目标检测

SSD目标检测介绍 SSD,全称Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法。使用Nvidia Titan X在VOC 2007测试集上,SSD对于输入尺寸300x300的网络,达到74.3%mAP(mean Average Precision)以及59FPS;对于512x512的网络,达到了76.9%mAP ,超…

Mouse Albumin ELISA Kit小鼠白蛋白ELISA试剂盒

白蛋白存在于所有哺乳动物和许多低等脊椎动物的血管内和血管外&#xff0c;是一种由肝脏合成的约67kDa的蛋白质。正常情况下&#xff0c;只有非常微量的白蛋白能逃过肾小球的重吸收&#xff0c;并被排泄到尿液中。ICL的Mouse Albumin ELISA Kit是一种高灵敏度的双抗体夹心法ELI…

基于“香港世界”的SLAM技术介绍

在视觉感知技术中&#xff0c;理解和描述复杂的三维室外场景至关重要&#xff0c;尤其是自动驾驶技术的发展要求对陌生环境具有更强的适应能力和鲁棒性。传统上&#xff0c;使用“曼哈顿世界”和“亚特兰大世界”模型来描述具有垂直和水平结构的城市场景。 当遇到像香港这样地形…

C++:类与面向对象static和this关键字其他关键字

类与面向对象 struct和class (1)struct是C中用户自定义类型&#xff0c;主要功能是对功能相关数据的封装 (2)struct不能直接封装函数&#xff0c;但可以通过封装函数指针来间接封装函数 (3)struct就是class的初级阶段&#xff0c;class在struct基础上做了很多扩展&#xff0c;便…

cartographer代码学习-扫描匹配(暴力搜索)

在学习栅格地图的时候&#xff0c;我们知道在栅格更新前会先进行扫描匹配获取当前机器人最有可能所在的位姿&#xff1a; // local map frame <- gravity-aligned frame// 扫描匹配, 进行点云与submap的匹配std::unique_ptr<transform::Rigid2d> pose_estimate_2d Sca…

[4]python+selenium - UI自动框架之封装基类BasePage页面

这部分内容是页面上的一些基本操作 from selenium.common.exceptions import TimeoutException, NoSuchElementException, WebDriverException, \StaleElementReferenceException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support im…

某安全公司DDoS攻击防御2024年6月报告

引言&#xff1a; 在2024年6月&#xff0c;网络空间的安全挑战汹涌澎湃。分布式拒绝服务&#xff08;DDoS&#xff09;攻击频发&#xff0c;针对云服务、金融科技及在线教育平台的精密打击凸显出当前网络威胁环境的严峻性。 某安全公司作为网络安全防护的中坚力量&#xff0c…

mybatis之动态标签

有些时候&#xff0c;sql语句where条件中&#xff0c;需要一些安全判断&#xff0c;例如按性别检索&#xff0c;如果传入的参数是空的&#xff0c;此时查询出的结果很可能是空的&#xff0c;也许我们需要参数为空时&#xff0c;是查出全部的信息。这是我们可以使用动态sql&…

代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形

接雨水 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 暴力解法 对计算接到的雨水&#xff0c;有两种方式&#xff0c;一是按照行来计算。 另一种是按列计算 按列计算容易不乱。基本思路如下&#xff1a; 对每列i进行循环&#xff0c;在循环中&#xff0c;找到该列左…

HarmonyOS Next开发学习手册——视频播放 (Video)

Video组件用于播放视频文件并控制其播放状态&#xff0c;常用于为短视频和应用内部视频的列表页面。当视频完整出现时会自动播放&#xff0c;用户点击视频区域则会暂停播放&#xff0c;同时显示播放进度条&#xff0c;通过拖动播放进度条指定视频播放到具体位置。具体用法请参考…

【JVM-02】垃圾收集(回收)算法

【JVM-02】垃圾收集/回收算法 1. 分代收集算法2. 标记-清除算法3. 标记-复制算法4. 标记-整理算法 1. 分代收集算法 分代收集(回收)算法根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集…

Kotlin中object关键字的作用

1、对象声明&#xff0c;通过这种方式创建一个单例对象。 object MySingleton{ fun function{ //方法代码块 } } 调用方式&#xff1a;MySingleton.function(),类似像Java的静态方法 2、在类内部声明伴生对象 class OutClass { companion object{ val value 1 fun method(…

【算法题】爬楼梯 (经典递归)

题 爬楼梯&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 输入&#xff1a; n 2 输出&#xff1a; 2 解释&#xff1a; 有两种方法可以爬到楼顶。 1 阶 1 阶 2 阶 示例 2&#x…

寒武纪实现高维向量的softmax进阶优化和库函数对比

关于寒武纪编程可以参考本人之前的文章添加链接描述,添加链接描述,添加链接描述 实验证明,axis=0和axis=-1的时候,手写softmax速度可以和库函数媲美,甚至于更甚一筹。 src/softmax.mlu #include <bang.h> #include

Nik Collection by DxO:摄影师的创意利器与调色宝典

在数码摄影的世界里&#xff0c;后期处理是摄影师们展现创意、调整细节、提升作品质量的重要步骤。而Nik Collection by DxO作为一款由DxO公司开发的强大照片编辑插件套件&#xff0c;为摄影师们提供了一套全面的、功能丰富的工具集&#xff0c;让他们的创意得以充分发挥。 Ni…

遇到多语言跨境电商系统源码问题?这里有解决方案!

从手机到电脑&#xff0c;从线下到线上&#xff0c;如今&#xff0c;跨境电商正在打破地域界限&#xff0c;成为全球贸易的新引擎。在这个全球化的背景下&#xff0c;跨境电商平台的运营也面临着一系列的挑战&#xff0c;其中之一就是多语言问题。如果你遇到了多语言跨境电商系…