【二分查找】【三种写法】——在排序数组中查找元素的第一个和最后一个位置#力扣hot100

非递减——>有序查找——>二分查找!

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

一、问题描述

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

二、示例说明

  1. 输入:nums = [5,7,7,8,8,10]target = 8,输出:[3,4]
    • 在给定的数组中,目标值8的开始位置是索引3,结束位置是索引4
  2. 输入:nums = [5,7,7,8,8,10]target = 6,输出:[-1,-1]
    • 目标值6不在给定的数组中,所以返回[-1,-1]
  3. 输入:nums = []target = 0,输出:[-1,-1]
    • 空数组中不存在任何目标值,返回[-1,-1]

三、提示信息

  1. 0 <= nums.length <= 105:数组的长度范围。
  2. -109 <= nums[i] <= 109:数组中的元素取值范围。
  3. nums是一个非递减数组。
  4. -109 <= target <= 109:目标值的取值范围。

四、解题思路

这道题,很自然会想到先用二分找到一个值,再从这个值往左右搜索扩展,找到整个区间。

  1. 首先使用二分查找找到目标值在数组中的一个位置。
  2. 然后分别从这个位置向左右两边扩展,找到目标值的开始位置和结束位置。

需要注意,本题要求时间复杂度为 O ( l o g n ) O(log n ) O(logn),在极端情况下,比如所有 n u m s nums nums数值一样时 O ( n ) O(n) O(n),会超时,
所以正确的解法是分别找左右两个边界,这样可以保证不会超时。
这样的话就很有意思了,我们要找的其实是左右两边第一个等于target的位置。
现在的难点是,我只会一般的二分查找,也就是不断通过收缩,找到第一个(右边的)target。

前面一直对二分查找的边界,开闭区间以及查找到的是左右边界不清楚,所以这里列出几种不同开闭区间的情况的二分查找代码,复习!

三种二分查找的通俗解释:
以下代码来源灵山大佬
一、二分查找函数
1.闭区间写法

  • 想象你在一个排好序的书架上找一本特定厚度的书(目标厚度就是target)。
  • 一开始,你把整个书架从最左边(left = 0)到最右边(right = len(nums) - 1)都作为搜索范围,这就像是确定了一个闭区间[left, right],你知道在这个范围内肯定能找到那本书或者确定它不在这个书架上。
  • 在找书的过程中,每次你都找到中间的位置(mid)看看这本书的厚度。如果中间这本书比目标厚度薄(nums[mid] < target),那你就知道目标书肯定在右边,所以你把搜索范围缩小到[mid + 1, right],也就是把左边的边界left移到mid + 1的位置。如果中间这本书的厚度大于等于目标厚度,那目标书可能在左边或者就是这本,所以你把搜索范围缩小到[left, mid - 1],把右边的边界right移到mid - 1的位置。
  • 一直这样找下去,直到左边的边界超过右边的边界(left > right),这时候left所指的位置就是最小的满足条件(书的厚度大于等于目标厚度)的位置。如果整个书架都没有满足条件的书,那left就会等于书架的长度,表示没有找到。
# lower_bound 返回最小的满足 nums[i] >= target 的 i
# 如果数组为空,或者所有数都 < target,则返回 len(nums)
# 要求 nums 是非递减的,即 nums[i] <= nums[i + 1]

# 闭区间写法
def lower_bound(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1  # 闭区间 [left, right]
    while left <= right:  # 区间不为空
        # 循环不变量:
        # nums[left-1] < target
        # nums[right+1] >= target
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1  # 范围缩小到 [mid+1, right]
        else:
            right = mid - 1  # 范围缩小到 [left, mid-1]
    return left

作者:灵茶山艾府
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/1980196/er-fen-cha-zhao-zong-shi-xie-bu-dui-yi-g-t9l9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. lower_bound2函数(左闭右开区间写法):

    • 同样是找书,这次你把书架分成左闭右开的区间。一开始左边是left = 0,表示你从第一本书开始看,右边是right = len(nums),表示你一直看到最后一本书的右边那个虚拟位置,这个区间就是[left, right)
    • 在找的过程中,如果中间这本书比目标厚度薄,你就把左边边界移到mid + 1,把搜索范围缩小到[mid + 1, right);如果中间这本书的厚度大于等于目标厚度,你就把右边边界移到mid,把搜索范围缩小到[left, mid)
    • 最后当左边边界和右边边界碰到一起的时候(left == right),你就找到了目标位置,返回leftright都可以,因为它们此时是同一个位置。
  2. lower_bound3函数(开区间写法):

    • 这次想象你站在书架外面,左边有一个虚拟的位置(left = -1),右边是书架的最后一本书的右边那个虚拟位置(right = len(nums)),这是一个开区间(left, right)
    • 找书过程和前面类似,如果中间这本书比目标厚度薄,你就把左边的虚拟位置移到mid,把搜索范围缩小到(mid, right);如果中间这本书的厚度大于等于目标厚度,你就把右边边界移到mid,把搜索范围缩小到(left, mid)
    • 最后当左边和右边的距离只有一本书的时候(left + 1 == right),你就找到了目标位置,返回right

二、searchRange函数

  1. 这个函数的目的是在一个排好序的书架(数组nums)中找到一本特定的书(目标值target)的出现范围。
    • 首先调用前面的lower_bound函数找到这本书可能出现的第一个位置start
    • 如果start等于书架的长度或者这个位置的书不是目标书,那就说明书架上没有这本书,直接返回[-1, -1]
    • 如果找到了这本书的开始位置,那么可以确定结束位置也存在。通过再次调用lower_bound函数找比目标书厚度大一点的书的位置,然后减一就是目标书的结束位置end
    • 最后返回这本书的出现范围[start, end]
在这里插入代码片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Paimon x StarRocks 助力喜马拉雅构建实时湖仓

作者&#xff1a;王琛 喜马拉雅数仓专家 小编导读&#xff1a; 本文将介绍喜马拉雅直播的业务现状及数据仓库架构的迭代升级&#xff0c;重点分享基于 Flink Paimon StarRocks 实现实时湖仓的架构及其成效。我们通过分钟级别的收入监控、实时榜单生成、流量监测和盈亏预警&am…

Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS

1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后&#xff0c;在原理图界面点击Launch&#xff0c;点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找到Generate All from Source。 2、在Generate Layout界面&#xff0c;选中“Instance”&#…

vscode插件-08 Golang

文章目录 Go安装其他必须软件 Go Go语言环境&#xff0c;只需安装这一个插件。然后通过vscode命令下载安装其他go环境需要的内容。 程序调试&#xff0c;需要创建.vscode文件夹并编写launch.json文件。 安装其他必须软件 ctrlshiftp&#xff0c;调出命令面板&#xff0c;输入…

Linux系列-vim的使用

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” vim的使用 vim是多模式编辑器&#xff0c;不同的是vim是vi的升级版本&#xff0c;它不仅兼容vi的所有指令&#xff0c;而且还有一些新的特性在里面&#xff0c;比如语法加亮&am…

强化学习DQN实践(gymnasium+pytorch)

Pytorch官方教程中有强化学习教程&#xff0c;但是很多中文翻译都太老了&#xff0c;里面的代码也不能跑了 这篇blog按照官方最新教程实现&#xff0c;并加入了一些个人理解 工具 gymnasium&#xff1a;由gym升级而来&#xff0c;官方定义&#xff1a;An API standard for rei…

2024快手面试算法题-生气传染

问题描述 思路分析 生气只会向后传播&#xff0c;最后一个生气的人一定是最长连续没有生气的人中的最后一个人&#xff0c;前提是前面得有一个人生气。 注意&#xff0c;一次只能传播一个人&#xff0c;比如示例1&#xff0c;第一次只会传播给第一个P&#xff0c;不会传播给第…

入门 | Kafka数据使用vector消费到Loki中使用grafana展示

一、Loki的基本介绍 1、基本介绍 Loki 是由 Grafana Labs 开发的一款水平可扩展、高性价比的日志聚合系统。它的设计初衷是为了有效地处理和存储大量的日志数据&#xff0c;与 Grafana 生态系统紧密集成&#xff0c;方便用户在 Grafana 中对日志进行查询和可视化操作。 从架构…

分类算法——逻辑回归 详解

逻辑回归&#xff08;Logistic Regression&#xff09;是一种广泛使用的分类算法&#xff0c;特别适用于二分类问题。尽管名字中有“回归”二字&#xff0c;逻辑回归实际上是一种分类方法。下面将从底层原理、数学模型、优化方法以及源代码层面详细解析逻辑回归。 1. 基本原理 …

【Spring MVC】DispatcherServlet 请求处理流程

一、 请求处理 Spring MVC 是 Spring 框架的一部分&#xff0c;用于构建 Web 应用程序。它遵循 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将应用程序分为模型&#xff08;Model&#xff09;、**视图&#xff08;View&#xff09;和控制器&#x…

现代数字信号处理I--最佳线性无偏估计 BLUE 学习笔记

目录 1. 最佳线性无偏估计的由来 2. 简单线性模型下一维参数的BLUE 3. 一般线性模型下一维参数的BLUE 4. 一般线性模型下多维参数的BLUE 4.1 以一维情况说明Rao论文中的结论 4.2 矢量参数是MVUE的本质是矢量参数中的每个一维参数都是MVUE 4.3 一般线性模型多维参数BLUE的…

QT(绘图)

目录 QPainter QPainter 的一些关键步骤和使用方法&#xff1a; QPainter 的一些常用接口&#xff1a; 1. 基础绘制接口 2. 颜色和画刷设置 3. 图像绘制 4. 文本绘制 5. 变换操作 6. 渲染设置 7. 状态保存与恢复 8. 其它绘制方法 示例代码1&#xff1a; 示例代码…

【js逆向学习】某多多anti_content逆向(补环境)

文章目录 声明逆向目标逆向分析逆向过程总结 声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的…

【安全解决方案】深入解析:如何通过CDN获取用户真实IP地址

一、业务场景 某大型互联网以及电商公司为了防止客户端获取到真实的ip地址&#xff0c;以及达到保护后端业务服务器不被网站攻击&#xff0c;同时又可以让公安要求留存网站日志和排查违法行为&#xff0c;以及打击犯罪的时候&#xff0c;获取不到真实的ip地址&#xff0c;发现…

Java | Leetcode Java题解之第524题通过删除字母匹配到字典里最长单词

题目&#xff1a; 题解&#xff1a; class Solution {public String findLongestWord(String s, List<String> dictionary) {int m s.length();int[][] f new int[m 1][26];Arrays.fill(f[m], m);for (int i m - 1; i > 0; --i) {for (int j 0; j < 26; j) {…

python爬虫抓取豆瓣数据教程

环境准备 在开始之前&#xff0c;你需要确保你的Python环境已经安装了以下库&#xff1a; requests&#xff1a;用于发送HTTP请求。BeautifulSoup&#xff1a;用于解析HTML文档。 如果你还没有安装这些库&#xff0c;可以通过以下命令安装&#xff1a; pip install requests…

Python实现深度学习模型预测控制(tensorflow)DL-MPC(Deep Learning Model Predictive Control

链接&#xff1a;深度学习模型预测控制 &#xff08;如果认为有用&#xff0c;动动小手为我点亮github小星星哦&#xff09;&#xff0c;持续更新中…… 链接&#xff1a;WangXiaoMingo/TensorDL-MPC&#xff1a;DL-MPC&#xff08;深度学习模型预测控制&#xff09;是基于 P…

简单的ELK部署学习

简单的ELK部署学习 1. 需求 我们公司现在使用的是ELK日志跟踪&#xff0c;在出现问题的时候&#xff0c;我们可以快速定为到问题&#xff0c;并且可以对日志进行分类检索&#xff0c;比如对服务名称&#xff0c;ip , 级别等信息进行分类检索。此文章为本人学习了解我们公司的…

神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛&#xff0c;和朋友一起参加做B题&#xff0c;波士顿房价预测&#xff0c;算是第一次自己动手实现一个简单的小网络吧&#xff0c;虽然很简单&#xff0c;但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison …

Spark的集群环境部署

一、Standalone集群 1.1、架构 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接客、资源管理和任务 调度&#xff0c;等同于YARN中的ResourceManager 从&#xff1a;Worker&#xff1a;计算节点&#xff1a;负责利…

[java][基础]JSP

目标&#xff1a; 理解 JSP 及 JSP 原理 能在 JSP中使用 EL表达式 和 JSTL标签 理解 MVC模式 和 三层架构 能完成品牌数据的增删改查功能 1&#xff0c;JSP 概述 JSP&#xff08;全称&#xff1a;Java Server Pages&#xff09;&#xff1a;Java 服务端页面。是一种动态的…