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

1.朴素二分查找

.二分查找

二分查找思路:
1.left=0,right=nums.size()-1(最后一个元素下标),取中间元素下标 mid=left+(right-left)/2 (防溢出)

2.nums[mid]>target ,说明mid右边的元素都大于target,就不用再从mid右边查找。right=mid-1

3.nums[mid]<target ,说明mid左边的元素都小于target,就不用再从mid左边查找。

left=mid+1

4.nums[mid]==tartget,找到目标值返回。

5.循环条件 left<=right,当left==right时,意味着只剩最后一个元素,有可能是目标值。

不断循环直到找到目标结果,或者left>right不满足循环条件。

class Solution {
public:int search(vector<int>& nums, int target) {int re=-1,left=0,right=nums.size()-1;while(left<=right){int i=left+(right-left)/2;if(nums[i]>target) right=i-1;else if(nums[i]<target) left=i+1;elsereturn i;}return re;}
};

2.查找区间左端点/右端点

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

这道题如果用朴素二分查找,虽然可以找到target==8的元素,但不一定就是目标值。

找到目标值再向左 向又查找不行吗?可以,但效率会降低。我们有其它方法可以更好的解决。

1.查找区间左端点

该方法对于朴素二分法不同的是,朴素二分法把区间分为3份,>target ==target <target。

查找区间左端点把区间分为2份,<target >=target(默认非递减)。

eg1.[5 7 7]  [8 8 10] 而目标值就在右区间的最左边。

1.如果mid落在左区间,mid指向的元素肯定不是目标值,可以让left=mid+1

2.如果mid落在右区间,mid指向的元素有可能是目标值,所以让right=mid 如果-1可能会跳过目标值。

所以right只会在右区间移动,而left最远只会到右区间的最左边。所以当left==right就可以求出结果。

3.循环条件为left<right,不能是left<=right,如果等于会一直循环,left==right

mid=(left+right)/2 mid值不变,还是在右区间,right=mid right值也不变。

4.mid的取值,mid=left+(right-left) 还是向上取整 mid=left+(right-left+1)?有什么区别?

如果只剩两个数[5 7 7]  [8 8 10] 的7 8。left指向7 right指向8,mid=left+(right-left+1) mid=1

此时mid指向8,落在右区间,right=mid。再取mid还是指向8,就会无限循环。

所以mid=left+(right-left) mid=0取靠左边的值,指向7,落在左区间,left=mid+1。此时left==right循环结束。

下面举2种极端情况

1.数组值全>target 只有右区间,right不断移动 left==0不动.left==right指向下标0

2.数组值全<arget 只有左区间,left不断移动 right==nums.szie()-1不动.left==right指向最后一个元素(因为mid=left+(right-left) mid=0取靠左边的值 不会出现mid==right left=mid+1越界的情况

 2.查找区间右端点

和查找左端点本质一样,但细节不同。

查找区间右端点把区间分为2份,<=target >target(默认非递减)。

eg1.[5 7 7 8 8] [ 10 ] 而目标值就在左区间的最右边。

1.如果mid落在右区间,mid指向的元素肯定不是目标值,可以让right=mid-1 

2.如果mid落在左区间,mid指向的元素可能是目标值,所以让left=mid 

所以left只会在左区间移动,而right最远只会到左区间的最右边。所以当left==right就可以求出结果。

3.循环条件为left<right,不能是left<=right,如果等于会一直循环,left==right

mid=(left+right)/2 mid值不变,还是在左区间,left=mid left值也不变。

4.mid的取值,mid=left+(right-left) 还是向上取整 mid=left+(right-left+1)?有什么区别?

如果只剩两个数[5 7 7 8 8 ][10] 的8 10。left指向8 right指向10,mid=left+(right-left) mid=0取靠左边的值 此时mid指向8,落在左区间,left=mid。再取mid还是指向8,就会无限循环。

所以mid=left+(right-left+1) mid=1取靠右边的值,指向10,落在右区间,right=mid-1。此时left==right循环结束。

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int le=-1,ri=-1;int left=0,right=nums.size()-1,mid=0;//处理边界情况if(nums.empty()) return {-1,-1};//取左端点下标while(left<right){mid=left+(right-left)/2;//取靠左边的值if(nums[mid]<target)left=mid+1;elseright=mid;}le=left;left=0,right=nums.size()-1;//取右端点下标while(left<right){mid=left+(right-left+1)/2;//取靠右边的值if(nums[mid]<=target)left=mid;elseright=mid-1;}ri=left;if(nums[left]==target) return {le,ri};else return {-1,-1}; //没找到的情况}
};

1.如果目标值是左端点,就把它套在右区间[5 7 7]  [8 8 10],让左边的+1来找,mid就要取靠左的值

2.如果目标值是右端点,就把它套在左区间[5 7 7 8 8 ][10],让右边的-1来找,mid就要取靠右的值

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

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

相关文章

Discuz 论坛开发一套传奇发布站与传奇开服表

Discuz 论坛开发一套传奇发布站与传奇开服表 随着互联网技术的飞速发展&#xff0c;网络游戏已成为人们休闲娱乐的重要方式之一。在众多网络游戏中&#xff0c;传奇系列以其独特的魅力吸引了大量忠实玩家。为了满足这些玩家的需求&#xff0c;并促进游戏信息的交流与分享&…

CSP-S2024游记

考前 前一天晚上提前回家了&#xff0c;晚上十一点上床睡觉&#xff0c;上午九点半自然醒了&#xff0c;在床上刷了半个小时手机&#xff0c;成功略过了早饭。 午饭前看了一会板子&#xff0c;tarjan、KMP之类的简单板子&#xff0c;但好像都没考到。 午饭吃的很简单&#x…

QT编辑框带行号

很可惜&#xff0c;qt的几个编辑框并没有相关功能。所以我们要自己实现一个。 先讲讲原理&#xff1a; QPlainTextEdit继承自QAbstractScrollArea&#xff0c;编辑发生在其viewport&#xff08;&#xff09;的边距内。我们可以通过将视口的左边缘设置一个空白区域&#xff0c;…

VScode插件:前端每日一题

大文件上传如何做断点续传&#xff1f; 在前端实现大文件上传的断点续传&#xff0c;通常会将文件切片并分块上传&#xff0c;记录每块的上传状态&#xff0c;以便在中断或失败时只上传未完成的部分。以下是实现断点续传的主要步骤和思路&#xff1a; 1. 文件切片 (File Slici…

ubuntu 20.4 安装 openssl 3.x

ubuntu 20.4 安装 openssl 3.x ubuntu 20.4 自带了openssl 1.0.2&#xff0c;升级为 openssl 3.x&#xff1a; # 下载 openssl 源代码压缩包 wget https://www.openssl.org/source/openssl-3.0.10.tar.gz# 安装编译包 sudo apt-get install -y g sudo apt-get install -y mak…

python把一张小图粘贴到一张大图上

在Python中&#xff0c;你可以使用Pillow库&#xff08;Python Imaging Library的一个分支&#xff09;来实现将一张小图粘贴到一张大图的左上角&#xff08;0, 0&#xff09;位置。以下是一个示例代码&#xff0c;展示了如何完成这一任务&#xff1a; 首先&#xff0c;确保你…

QtCreator通过CMake多文件编译.cpp、.qss、.h、.ui文件,达到MVC三层架构的效果

博主在构建C项目的时候&#xff0c;一般都喜欢将头文件和源文件分开为不同的文件夹&#xff0c;比如include目录下只存放.h文件和.ui文件&#xff0c;src目录下只存放.cpp和.qss文件&#xff0c;res目录下只存放图片、音频等文件&#xff0c;这时候使用CMake对项目进行分文件管…

qml圆形图片,qml圆形头像制作

代码比较简单&#xff0c;就不细讲了&#xff0c;大家直接看下面源码吧&#xff01;如果对你有所帮助&#xff0c;可以帮角角点个关注嘛&#xff1f; import QtQuick import QtQuick.Effects import Qt5Compat.GraphicalEffectsWindow {width: 640height: 480visible: truetit…

使用代理服务器后sse数据合并问题

如果是使用本地代理服务器devServer compress:false,如果是发布到生产环境下的代理服务器nginx 增加如下配置&#xff0c;该配置同时支持websocket和sse proxy_http_version 1.1; #设置代理请求使用 HTTP/1.1 版本。WebSocket 需要 HTTP/1.1&#xff0c;因为它支持持久连接和更…

【python库】PandasGUI介绍

Github地址&#xff1a;https://github.com/adamerose/PandasGUI 在数据科学和分析过程中&#xff0c;数据的可视化和交互操作是非常重要的环节。尽管 Pandas 是一个强大的数据处理库&#xff0c;但其缺乏用户友好的图形界面&#xff0c;这使得数据探索和分析变得相对繁琐。pan…

【每日一题】LeetCode - 盛最多水的容器

给定一个长度为 n 的整数数组 height。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。要求找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 输入示例&#xff1a; height [1,8,6,2,5,4,8,3,7]输出&#xff1a; 4…

2024年1024程序人生总结

2024-1024 0.大环境0.1.经济0.2.战争 1.我的程序人生1.1.游戏 2.节日祝福 0.大环境 今年的1024最大的感触就是没有节日氛围&#xff0c;往年公司还会准备节日礼物&#xff0c;今年没有&#xff0c;由此可见大环境有多么糟糕。 除此之外&#xff0c;就是到公司应聘的程序员越来…

如何理解前端与后端开发

前端与后端开发是构建现代Web应用的两个主要部分&#xff0c;它们共同工作&#xff0c;为用户提供完整的在线体验。以下是对前端和后端开发的理解和它们之间的主要区别&#xff1a; 前端开发&#xff08;客户端开发&#xff09; 用户界面&#xff08;UI&#xff09;&#xff…

2025前端面试-浏览器的事件循环和浏览器的事件循环的区别是什么---002

浏览器的事件循环和浏览器的事件循环的区别是什么 JS是单线程的浏览器中JS执行和DOM渲染公用一个线程异步 异步中又有宏任务和微任务 宏任务 setTimtout setInterval微任务 Promise async await(先执行同步任务后执行异步任务&#xff09;微任务在下一轮DOM渲染之前执行&…

Python快速入门教程

目录 1. Python 简介 2. 环境准备 3. 第一个 Python 程序 4. 变量与数据类型 5. 基本操作与控制结构 6. 函数与模块 7. 实践项目 结语 Python 是一种非常友好的编程语言&#xff0c;特别适合初学者。它的语法简洁&#xff0c;容易上手&#xff0c;并且广泛应用于各种领…

C++结合图形编程与物联网:你更偏向哪种方式来学习信息学奥赛?

随着信息学奥赛在全国范围内的热度逐年攀升&#xff0c;学生和家长们越来越重视如何有效备赛。传统的编程学习方式侧重于算法和数据结构&#xff0c;但随着科技的发展&#xff0c;图形化编程与物联网&#xff08;IoT&#xff09;项目逐渐成为新兴的学习路径。通过C结合图形化编…

Rust 力扣 - 1. 两数相加

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们使用一个全局的备忘录&#xff0c;然后我们遍历数组&#xff0c;如果当前元素在备忘录里面找到了&#xff0c;就返回备忘录里面记录的下标和当前下标记录&#xff0c;没找到就把当前元素匹配的元素和当前元素…

N.Katz对数学的贡献我一无所知

当年我在Columbia大学数学系&#xff0c;每次数论seminar我都听&#xff0c;这个系列seminar是由Goldfeld跟Szpiro主持的&#xff0c;那次本来Katz是应邀来做报告的&#xff0c;但他却对Goldfeld出言不逊&#xff08;也对广大听众&#xff09;&#xff0c;言语中带着训斥&#…

人工智能_神经网络103_感知机_感知机工作原理_感知机具备学习能力_在学习过程中自我调整权重_优化效果_多元线性回归_逻辑回归---人工智能工作笔记0228

由于之前一直对神经网络不是特别清楚,尤其是对神经网络中的一些具体的概念,包括循环,神经网络卷积神经网络以及他们具体的作用,都是应用于什么方向不是特别清楚,所以现在我们来做教程来具体明确一下。 当然在机器学习之后还有深度学习,然后在深度学习中对各种神经网络的…

Java对称加密:AES 高级加密标准

1、对称加密简述 对称加密&#xff0c;又称对称密钥加密或私钥加密&#xff0c;是一种在加密和解密过程中使用相同一个密钥的加密算法。这种加密方式的核心在于&#xff0c;发送方使用某个密钥对数据进行加密&#xff0c;接收方则使用完全相同的密钥对数据进行解密。由于加密和…