找出目标值在数组中的开始和结束位置(二分查找)

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums 是一个非递减数组
  • -109 <= target <= 109

 方法一:


class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {vector<int> result = {-1, -1};int left = 0;int right = nums.size() - 1;while (left <= right) {  //二分查找算法的核心部分int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else {right = mid - 1;}}if (left < nums.size() && nums[left] == target) {result[0] = left;  //找到的话就把起始值记录为left} else {return result;    //到了数组结尾还没找到那就直接返回-1,-1}right = nums.size() - 1;    //重置 right 为数组的最后一个索引。while (left <= right) {    //第二次二分查找int mid = left + (right - left) / 2;if (nums[mid] <= target) {    //这里条件不一样需要注意left = mid + 1;} else {right = mid - 1;}}result[1] = right;    //更新终止值return result;}
};

 这道题可以使用二分查找的原因主要在于题目中的数组是非递减顺序排列的整数数组

vector<int> result = {-1, -1}; 

初始化一个整数向量 result,其初始值为 {-1, -1}

int mid = left + (right - left) / 2;

计算当前查找范围的中间索引 mid。这里采用的计算方式是为了避免可能的整数溢出。

if (nums[mid] < target)

如果 nums[mid] 小于 target,说明目标值位于 mid 的右侧,因此将 left 移动到 mid + 1,缩小查找范围。

如果 nums[mid] 大于或等于 target,则目标值位于 mid 的左侧(包括 mid 本身),所以将 right 移动到 mid - 1,缩小查找范围。

left < nums.size()

  • 这个条件确保 left 不会超出 nums 数组的范围。因为 left 在查找的过程中可能已经移动到了数组的末尾,如果 left 超过了数组的索引范围,直接访问 nums[left] 会导致运行时错误。

nums[left] == target

  • 这个条件检查 nums[left] 是否等于 target。如果 left 所指向的元素等于目标值,说明找到了目标值的起始位置。此时,将 result[0] 更新为 left,即目标值在数组中的起始索引。 

 如果 left 不在有效范围内,或者 nums[left] 不等于 target,这说明数组中不存在目标值。此时直接返回 result,它的值仍然是 [-1, -1],表示未找到目标值。

为什么两次二分查找的 if 语句不一样:

在第一次二分查找中,我们的目标是找到 target起始位置。如果存在起始值,当leftright 相遇时的相遇点即为起始值 target,这个时候需要保证 left 为 target,就需要right 左移来退出循环。

而在第二次二分查找中,我们的目标是找到 target结束位置。我们需要保证right 为 target,就需要 left右移来退出循坏。

二分查找的精髓通过每次比较中间值来逐步缩小查找范围,保证时间复杂度为 O(log⁡n)

 

方法二:

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int start = find(nums, target);int end = find(nums, target + 1) - 1;if (start == -1 || end < start) {return {-1, -1};}return {start, end};}int find(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return left;}
};

利用 find(nums, target) 找到 target 的第一个位置,再利用 find(nums, target + 1) 找到比 target 大的第一个元素的位置,从而间接确定 target 的结束位置。

如果数组中不存在第一个大于 target 的元素,那么 find(nums, target + 1) 的结果将会是 nums.size(),end的值为 nums.size() - 1

假设 nums = [5, 7, 7, 8, 8, 10]target = 8

  • find(nums, 8) 返回 3,因为 8 的第一个位置在索引 3
  • find(nums, 9) 返回 5,因为 98 大,且索引 5 是第一个大于 8 的位置。
  • end = find(nums, 9) - 1 等于 4,所以返回 [3, 4]

 

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

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

相关文章

0xGame 2024 [Week 4] Jenkins

1.前言 由于好久没做web题了&#xff0c;所以今天来尝试来做一波web题&#xff0c;仅供刷题记录。 2.题目 这个给的提示对于小白来说实在是友好的过劲。 3.分析 上网搜到一个关于Jenkins的历史漏洞&#xff0c;下面链接可供参考 https://blog.csdn.net/2301_80127209/arti…

yolov8训练及测试(ubuntu18.04、tensorrt、ros)

1 数据集制作 1.1标注数据 Linux/Ubuntu/Mac 至少需要 Python 2.6 &#xff08;推荐使用 Python 3 或更高版本 及 PyQt5&#xff09; Ubuntu Linux (Python 3 Qt5) git clone https://gitcode.com/gh_mirrors/la/labelImg.git sudo apt-get install pyqt5-dev-tools cd lab…

Nginx 反向代理(解决跨域)

文章目录 前言一、同源策略二、跨域是什么&#xff1f;三、Nginx解决跨域1.前端示例代码2.说明 四、nginx反向代理配置五、启动nginx六、最终效果总结 前言 Nginx反向代理解决跨域 一、同源策略 定义&#xff1a;同源策略&#xff08;Same-Origin Policy&#xff09;是指浏览…

clickhouse配置用户角色与权限

首先找到user.xml文件&#xff0c;默认在/etc/clickhouse-server路径下 一、配置角色 找到标签定义 <aaaa><readonly>1</readonly><allow_dll>0</allow_dll> </aaaa>其中aaaa为角色名称&#xff0c;readonly为只读权限&#xff08;0–代表…

ssm《数据库系统原理》课程平台的设计与实现+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容…

多渠道流量获取策略提升网站访问量的有效方法

内容概要 在当今数字时代&#xff0c;企业面临着越来越激烈的竞争&#xff0c;流量获取变得极为重要。多渠道流量获取不仅可以增加网站的访问量&#xff0c;还能够有效提升品牌的知名度和影响力。通过整合多种渠道&#xff0c;企业能够更好地触达目标受众&#xff0c;实现精准…

kafka实时返回浏览数据

在安装完kafka(Docker安装kafka_docker 部署kafka-CSDN博客)&#xff0c;查看容器是否启动&#xff1a; docker ps | grep -E kafka|zookeeper 再用python开启服务 from fastapi import FastAPI, Request from kafka import KafkaProducer import kafka import json import …

【MyBatis源码】BoundSql分析

基础 BoundSql是对SQL语句及参数信息的封装&#xff0c;它是SqlSource解析后的结果。Executor组件并不是直接通过StaticSqlSource对象完成数据库操作的&#xff0c;而是与BoundSql交互。BoundSql是对Executor组件执行SQL信息的封装&#xff0c;具体实现代码如下&#xff1a; …

Vue3 + Pinia:轻松读取数据的终极指南

Hey小伙伴们&#xff01;今天我们要聊的是Vue3中一个非常强大的状态管理库——Pinia。Pinia不仅简化了状态管理的复杂度&#xff0c;还提供了丰富的功能&#xff0c;让你在读取数据时更加得心应手。让我们一起来看看如何在Vue3项目中使用Pinia读取数据吧&#xff01;&#x1f3…

A Consistent Dual-MRC Framework for Emotion-cause Pair Extraction——论文阅读笔记

前言 这是我第一次向同学院同年级的学生和老师们汇报的第一篇论文,于2022年发表在TOIS上,属于CCF A类,主要内容是将MRC应用到情感原因对抽取中。 论文链接:用于情绪-原因对提取的一致双 MRC 框架 |信息系统上的 ACM Transactions 这里我就不放上我自己翻译的中文版还有我…

【Linux系统】—— 基本指令(一)

【Linux系统】—— 基本指令&#xff08;一&#xff09; 1 「ls」指令1.1 初识 「ls」 指令1.2 「ls -l」1.3 认识文件1.4 「ls -l」显示的内容1.5 如何区分文件类型1.6 「ls -a」1.7 混合使用命令行选项1.8 「ls」查看指定目录下文件1.9 「ls」 指令常用命令行选项 2 「pwd」 …

虚拟机安装Ubuntu系统

1、下载虚拟机 虚拟机下载链接 链接&#xff1a;https://pan.baidu.com/s/1JTSDhcw-_uQfMYPQbNuJ9w 提取码&#xff1a;hkf0 秘钥 JU090-6039P-08409-8J0QH-2YR7F 2、Ubuntu镜像下载 下载Ubuntu桌面系统 | Ubuntu 3、设置虚拟机 参考下文 虚拟机安装Ubuntu教程(详细)-C…

js,ts控制流程

摘要&#xff1a; 在 JavaScript 和 TypeScript 中&#xff0c;控制流程是指程序执行的顺序和条件判断。以下是一些常见的控制流程结构&#xff0c;包括条件语句、循环语句和函数调用等。 1. 条件语句&#xff1a; if 语句 let condition true;if (condition) {console.log(C…

计组-Cache的基本概念,计算Cache+主存的平均周期

由于寄存器是集成在CPU中且容量极小&#xff0c;所以我们用Cache来提高速度&#xff0c;在无寄存器时其当做访问速度最快的 Cache的命中率: 是指当CPU要处理某个数据时&#xff0c;首先会考虑在Cache里面去读取&#xff0c;当需要读取的数据在Cache里面时&#xff0c;此时这个…

《大数据与人工智能:提升数据质量与数量的利器》

《大数据与人工智能&#xff1a;提升数据质量与数量的利器》 一、大数据与人工智能的融合趋势二、大数据增加数据数量的方法&#xff08;一&#xff09;不同途径的数据增量&#xff08;二&#xff09;数据增强的多样方法 三、人工智能提升数据数量的手段&#xff08;一&#xf…

【JAVA】Java基础—Java概述:Java的特点

Java语言因其独特的设计理念和强大的功能&#xff0c;在软件开发领域获得了广泛的应用。以下是Java的几个主要特点的详细说明&#xff0c;以及通俗易懂的例子来帮助理解这些概念。 1. 跨平台性 理论说明 Java的跨平台性是其最显著的特点之一&#xff0c;得益于Java虚拟机&am…

算法中使用的数据结构解释*

算法中使用的数据结构解释 在算法的执行过程中&#xff0c;需要有能够容纳临时数据的内存数据结构。数据结构的有效实施需要选择适当的数据结构。迭代或递归算法需要专门为其逻辑设计的数据结构。 也有人表述为容器&#xff0c;存放数据的容器。 在递归算法的情况下&#xff0c…

UE4安卓Gradle工程中的libUE4.so的生成原理

流程图 流程图放在最前面&#xff0c;下面是讲解。 libUE4.so 问&#xff1a;在UE4安卓开发中&#xff0c;libUE4.so即是符号表&#xff0c;又是引擎代码native&#xff0c;是吗&#xff1f; 答&#xff1a;是的&#xff0c;libUE4.so在UE4安卓开发中既包含符号表&#xff0c;…

一文囊括风控建模中的变量筛选方法

风控建模在金融领域中起着至关重要的作用,特别是在信贷和支付领域。为了构建稳定和有效的风控模型,变量筛选是一个必不可少的步骤。本文将详细介绍几种在风控建模中常用的变量筛选方法。 文章目录 一、变量自身分布稳定性1 变量PSI值计算2 长期趋势图二、变量和目标值的强相关…

C4.【C++ Cont】C++数据类型和typedef的补充说明

1.数据类型 C同C语言的一样的数据类型不在赘述,参见3.【C语言】内置数据类型,这里只讲不同点 1.在C中,布尔类型包含在头文件iostream中,不用像C语言一样包含stdbool.h 布尔类型变量的定义写法和C语言不同,只能写成 bool a true; bool b false; bool不可写成_Bool或Bool …