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

news2024/11/19 23:23:57

在这里插入图片描述

个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《算法》

文章目录

  • 前言
  • 一、题目解析
  • 二、解题思路
    • 1. 暴力查找
    • 2. 一次二分查找 + 部分遍历
    • 3. 两次二分查找分别查找左右端点
      • 1.查找区间左端点
      • 2. 查找区间右端点
  • 三、代码实现
  • 总结


前言

本篇文章仅是作为小白的我的一些理解,,如果有错误的地方,希望大佬们指出。


  • 题目链接: 34. 在排序数组中查找元素的第一个和最后一个位置

一、题目解析

在这里插入图片描述
本题数组元素不唯一,可能存在多个target,我们就是要找到target区间中的左端点与右端点。
在这里插入图片描述
如果没有target区间,则返回{-1, -1}

二、解题思路

1. 暴力查找

直接遍历数组,如果可以查找到target则返回第一次与最后一次遇到target的下标,如果不能查找到target则返回{-1, -1}。
时间复杂度:O(n)

2. 一次二分查找 + 部分遍历

优先使用二分查找target,如果可以查找到,就从该下标开始向左向右遍历数组,返回最左边与最右边的target。如果不能查找到,返回{-1, -1}
时间复杂度:O(logn + n)

对于{3,3,3,3,3,3,3,3} target = 3,时间复杂度会退化为O(n)

3. 两次二分查找分别查找左右端点

1.查找区间左端点

我们对示例1使用 “ 二段性 ” 可以发现示例一被target分成了两部分,小于target部分{5, 7, 7}和大于等于target部分{8, 8, 10}。
在这里插入图片描述
如果中点mid到小于target的部分,区间[ left, mid ]这一区间都小于target,不可能是target区间的左端点,那么left = mid + 1;
如果中点mid到大于等于target的部分,区间[ mid, right ]这一区间都大于等于target, 其中mid有可能是target区间的左端点,那么right = mid;
在这里插入图片描述


细节处理

  • 循环条件:left < right
    如果循环条件为left <= right就会死循环。
    在这里插入图片描述

如上图4所示,nums[mid] >= target,right = mid。此时right依然与left指向同一个元素。

  • 求mid的操作
    向下取整:mid = left + (right - left)/2 向上取整:mid = left + (right - left + 1)/2;二者主要区别在与如果区间[ left, right]中的元素个数是偶数时,向下取整取的是中间两个数中左边的数,向上取整取的是中间两个数中右边的数。
    此时查找区间左端点,求mid使用向上取整会导致死循环。
    在这里插入图片描述

2. 查找区间右端点

查找区间右端点思路与查找区间左端点类似。
我们使用“二段性”发现示例一被target分成了两部分,小于等于target部分{5, 7, 7, 8, 8} 和大于target部分{10}。
在这里插入图片描述
如果点mid到小于等于target的部分,区间[ left, mid ] 这一区间都小于等于target,其中mid可能就是target区间的右端点,那么left = mid;
如果点mid到大于target的部分,区间[ mid, right ]这一区间都大于target,不可能是target区间的右端点,那么right= mid - 1;
在这里插入图片描述


细节处理

  • 循环条件:left < right, 理由与查找左端点使的循环条件相同,如果循环条件为left <= right会死循环
    在这里插入图片描述
    如上图4所示,nums[mid] <= target,left = mid, 此时left依然与right指向同一个元素。

  • 求mid的操作,这里就要用向上取整的方法 mid = left + (right - left + 1)/2
    此处查找区间右端点,如果使用向下取整会导致死循环
    在这里插入图片描述

三、代码实现

两次二分查找分别查找左右端点

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> ret({-1, -1});

        int n = nums.size();
        if(n == 0)
            return ret;

        int left = 0, right = n-1;
        // 查找左端点
        while(left < right)
        {
            int mid = left + (right - left)/2;
            if(nums[mid] < target)
                left = mid+1;
            else
                right = mid;
        }
        if(nums[right] == target)
            ret[0] = right;
        
        // 查找右端点
        left = 0, right = n-1;
        while(left < right)
        {
            int mid = left + (right - left + 1)/2;
            if(nums[mid] > target)
                right = mid - 1;
            else
                left = mid;
        }
        if(nums[right] == target)
            ret[1] = right;

        return ret;
    }
};

总结

以上就是我对于在排序数组中查找元素的第一个和最后一个位置的理解。感谢支持!!!
在这里插入图片描述

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

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

相关文章

GCN详解

a ⃗ \vec{a} a 向量 a ‾ \overline{a} a 平均值 a ‾ \underline{a} a​下横线 a ^ \widehat{a} a (线性回归&#xff0c;直线方程) y尖 a ~ \widetilde{a} a a ˙ \dot{a} a˙ 一阶导数 a \ddot{a} a 二阶导数 H(l)表示l层的节点的特征 W(l)表示l层的参数 D ~ \widet…

Kafka客户端核心参数详解

这一部分主要是从客户端使用的角度来理解 Kakfa 的重要机制。重点依然是要建立自己脑海中的 Kafka 消费模型。Kafka 的 HighLevel API 使用是非常简单的&#xff0c;所以梳理模型时也要尽量简单化&#xff0c;主线清晰&#xff0c;细节慢慢扩展。 一、从基础的客户端说起 Kaf…

iphone怎么传大量照片到电脑,这四招你要学会

如果你喜欢用iPhone拍照、总会遇到要把大量照片从iPhone传输到电脑的情况&#xff0c;要是你对这方面不熟悉就很容易浪费时间。下面小编就介绍几种方法可以快速高效的传大量照片到电脑上去。 iPhone传输照片到电脑 方法一&#xff1a;使用iMazing传输 推荐度★★★★★ 有了i…

操作系统八股

1、请你介绍一下死锁&#xff0c;产生的必要条件&#xff0c;产生的原因&#xff0c;怎么预防死锁 1、死锁 两个或两个以上的进程在执行过程中&#xff0c;因争夺共享资源而造成的一种互相等待的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系统处…

【Spring Boot】日志文件

日志文件 一. 日志文件有什么用二. 日志怎么用三. ⾃定义⽇志打印1. 在程序中得到⽇志对象2. 使⽤⽇志对象打印⽇志3. ⽇志格式说明 四. 日志级别1. ⽇志级别有什么⽤2. ⽇志级别的分类与使⽤ 五. 日志持久化六. 更简单的⽇志输出—lombok1. 添加 lombok 依赖2. 输出⽇志3. lom…

(六)正点原子STM32MP135移植——内核移植

目录 一、概述 二、编译官方代码 三、移植 四、编译 一、概述 前面已经移植好了TF-A、optee、u-boot&#xff0c;在u-boot能正常跑起来的情况下&#xff0c;现在来移植内核。 二、编译官方代码 进入kernel目录 2.1 解压源码、打补丁 /* 解压源码 */ tar xf linux-6.1.28.…

【算法|动态规划No.13】leetcode LCR 166. 珠宝的最高价值

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

HVDC-MMC互连(1000MW,±320KV)使用聚合MMC模型进行优化的SPS模拟

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型概述&#xff1a; 本示例展示了一个SimPowerSystems&#xff08;SPS&#xff09;模型&#xff0c;使用基于模块化多电平变换器&#xff08;MMC&#xff09;技术的电压源换流器&#xff08;VSC&#xff09…

C++基础知识(四) -- 内联函数

概念 宏 提到内联函数就不得不提一下c语言里面的宏了&#xff0c;也可以说c的内联函数是从c语言里面的宏进化过来了的。 宏属于是暴力替换&#xff0c;过于生硬了&#xff0c;宏的缺点有如下 宏缺点&#xff1a; 1、不能调试 2、没有类型安全的检查 3、有些场景下非常复杂,容易…

数据结构之带头双向循环链表

目录 链表的分类 带头双向循环链表的实现 带头双向循环链表的结构 带头双向循环链表的结构示意图 空链表结构示意图 单结点链表结构示意图 多结点链表结构示意图 链表创建结点 双向链表初始化 销毁双向链表 打印双向链表 双向链表尾插 尾插函数测试 双向链表头插 …

《Spring Boot前世今生》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

VMware Workstation Pro详解

零、文章目录 VMware Workstation Pro详解 1、虚拟机介绍 &#xff08;1&#xff09;介绍 VMware Workstation Pro 是行业标准桌面 Hypervisor&#xff0c;使用它可在 Windows 或 Linux 桌面上运行 Windows、Linux 和 BSD 虚拟机。VMware官网地址&#xff1a;https://www.v…

【Python】如何使用PyInstaller打包自己写好的代码

使用PyInstaller打包自己写好的代码 零、需求 最近接到一个小单&#xff0c;需要批量修改文档内容&#xff0c;用Python做好后要打包成exe程序给客户的Win7电脑使用&#xff0c;此时需要用到PyInstaller打包自己的代码&#xff0c;想到还要有给用户试用的需求&#xff0c;所以…

第六章 数字化工作方法与应用

第一节 题目 A C 第二节 题目 A C B D A 右侧原因型&#xff0c;在左侧是对策型。主要记得右侧是原因行就可以了。 C B D 字面意思。 ABCD CD

笔训【day3】

目录 选择题 1、二维数组初始化 2、[]优先级高于* ​编辑 3、for初始化只执行一次​编辑 4、大小端 编程题 1、字符串中找出最长连续数字串 2、数组中出现次数超过一半的数 选择题 1、二维数组初始化 C&#xff1a;多初始化了一行 D&#xff1a;不能中间用两个逗号跳过。…

外包做了3个月,技术退步明显。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;17年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

【群智能算法】光学显微镜算法 OMA算法【Matlab代码#59】

文章目录 【获取资源请见文章第4节&#xff1a;资源获取】1. 光学显微镜算法&#xff08;OMA&#xff09;1.1 物镜放大倍数1.2 目镜放大倍数 2. 部分代码展示3. 仿真结果展示4. 资源获取说明 【获取资源请见文章第4节&#xff1a;资源获取】 1. 光学显微镜算法&#xff08;OMA&…

win10睡眠快捷方式

新建快捷方式 如下图 内容如下 rundll32.exe powrprof.dll,SetSuspendState 0,1,0 下一步 点击完成即可。 特此记录 anlog 2023年10月6日

ssm+vue的培训机构运营管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的培训机构运营管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

Linux工具(三)

继Linux工具&#xff08;一&#xff09;和Linux工具&#xff08;二&#xff09;&#xff0c;下面我们就来讲解Linux最后的两个工具&#xff0c;分别是代码托管的版本控制器git和代码调试器gdb。 目录 1.git-版本控制器 从0到1的实现git代码托管 检测并安装git 新建git仓库…