二分查找法(查找左右端点)

news2024/9/23 1:32:09

前言

本文将会向您介绍二分查找法(查找左右端点),关于朴素的二分查找法已经在之前讲过了朴素二分查找您可以点此超链接

查找右端点

如果您仅仅是想要参考如何查找左右端点,可以直接跳转到下文的模板处

ps:以下是本文涉及到的一些名词
tar(target目标值):示例中所要查找的值
mid:中间位置下标
vue(value):中间位置的值与mid对应
R:right
L:left
ps:文中的图例皆来自手写笔记

首先你应该先要记住:查找左右端的思想->二段性

待查找目标值tar:3
我们将区间分为两段,分别是小于等于3,和大于3
你肯定会有疑问:为什么要这么分
->原因是我们每次计算的vue中间位置处的值要么是在大于等于tar区间内的,也有可能是在小于tar区间内的,已经涵盖了查找右端点的所有可能性,助于理解罢了
参考代码片段

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

在这里插入图片描述
左区间:
在这里插入图片描述

计算中间位置mid = L + (R - L + 1)/ 2(为什么会是这个计算式,见后文)
更新left(L):L = mid,本质上还是缩小区间
注意:L缩小区间不能是mid + 1,如果mid本身就是右端点,那么就永远查找不到了
更新完L,继续进循环重复步骤
在这里插入图片描述
右区间
在这里插入图片描述
由于要查找的target目标值不在此区间内,我们依旧还是模拟这个过程(虽然表面上已经不用再分析了),因此缩小区间范围
更新R(right) = mid - 1
尽量缩的小一点,因此给了mid - 1
在这里插入图片描述
继续进入循环,直至循环结束
循环条件讨论:left < right
为什么不像朴素的二分法一样left<=right呢
第一种情况:有结果
第二种情况:数组中的元素都比目标值大
第三种情况:数组中的元素都比目标值小
这三种情况我们都只需要单独判断最终位置的值和target的关系即可
如果这里用left<=right当循环条件判断,看第一种情况,当left == right的时候,会一直命中此条件,L=mid, 一直执行此条件,导致死循环

在这里插入图片描述

在这里插入图片描述

上文中留下了一个疑问:为什么我们查找右端点的中点公式是mid = L + (R - L + 1)/ 2
原因是:当剩余两个数的时候,如果target值是左边的数,那么我们采用mid = L + (R - L )/ 2
计算中点,中点计算出来的值将会是左侧的数,将会一直命中L = mid,导致死循环
在这里插入图片描述

查找左端点

在这里插入图片描述
与查找右端点一样,我们将模拟所有的情况,因此我们把区间分为小于tar, 和大于等于tar
左区间
在这里插入图片描述

由于左区间不是target值所在的区间
我们更新L(left)的值,尽量向右移动(相比于给mid),因此给了mid + 1,然后继续循环直至循环结束
在这里插入图片描述
缩小右区间:
在这里插入图片描述
更新R(right),将R向左移,但是不能是mid-1,因为mid处的值可能就是目标值,要不然就永远找不到了
在这里插入图片描述
循环条件:left < right
为什么不是left <= right与查找右端点时的分析一样,结果会导致死循环,这里就不再多赘述
在这里插入图片描述
中点讨论:
注意:这里的中点计算公式是与查找右端点不同的!!!
当target在靠右的数的时候,第二个mid计算出的mid将会一直在tar位置,并会一直命中R=mid,会导致死循环
在这里插入图片描述

因此查找左端点的中点公式还是用mid = L + (R - L)/ 2

查找左右端点模板

while(left < right)
{
int mid = left + (right-left)/2
if(...) left = mid + 1;
else right = mid;
}
while(left < right)
{
int mid = left + (right - left + 1)/2
if(...) left = mid;
else right = mid - 1;
}

例题

如果你已经看完了上文,并能够自己分析出来,那么你可以尝试下面这道题
在排序数组中查找元素的第一个和最后一个位置

小结

今日的分享就到这里啦,如果本文存在疏漏或错误的地方还请您能够指出!

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

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

相关文章

Linux常用的指令(2023.10.27)

文章目录 查看目录下文件的大小虚拟环境相关删除虚拟环境多版本的cuda切换修改虚拟环境名称 文件的移动、删除和复制文件的复制文件的删除文件的移动 查看目录下文件的大小 du&#xff08;disk usage 磁盘使用率&#xff09;命令查看当前目录和子目录文件夹、文件大小情况 du …

YOLOv7优化:渐近特征金字塔网络(AFPN)| 助力小目标检测

💡💡💡本文改进:渐近特征金字塔网络(AFPN),解决多尺度削弱了非相邻 Level 的融合效果。 AFPN | 亲测在多个数据集能够实现涨点,尤其在小目标数据集。 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀🚀🚀…

开源投票系统源码至尊版带礼物道具 无限多开 盈利模式超丰富

网络投票系统已经成为各种活动、比赛、评选等场景中不可或缺的一部分。春哥团队开源投票系统源码至尊版是一种功能强大、灵活可定制的投票系统&#xff0c;不仅具有高度的安全性和稳定性&#xff0c;还支持多种盈利模式&#xff0c;含完整版代码包&#xff0c;支持投票礼物道具…

设备的分配与回收(考虑因素,数据结构,分配步骤)

目录 1.设备分配时应考虑的因素1.设备的固有属性2.设备分配算法3.设备分配中的安全性1.安全分配方式2.不安全分配方式 2.静态分配与动态分配3.设备分配管理中的数据结构1.“设备、控制器、通道”之间的关系2.设备控制表&#xff08;DCT)3.控制器控制表(COCT)4.通道控制表&#…

P1868 饥饿的奶牛

根据题意可以知道是一个动态规划&#xff0c;看完数据范围之后可以知道是一个线性DP。 解决方法有点类似于背包问题&#xff0c;枚举背包的每一个空间。 如果把坐标轴上每个点都看成一个块儿&#xff0c;只需要按顺序求出前 i 个块儿的最大牧草堆数&#xff0c;f[i] 就是前i的…

基于机器视觉的火车票识别系统 计算机竞赛

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的火车票识别系统 该项目较为新颖&#xff0c;适合作为竞赛…

BUUCTF zip伪加密 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;得到一个zip压缩包。 密文&#xff1a; 解题思路&#xff1a; 1、刚开始尝试解压&#xff0c;看到了flag.txt文件&#xff0c;但需要解压密码。结合题目&#xff0c;确认这是zip伪加密&#…

【0基础学Java第一课】-- 初始Java

目录 1. 初识java1.1 Java是什么1.2 Java应用领域1.3 Java语言发展简史1.4 Java语言特性1.5 JRE与JDK1.6 Java开发环境1.6.1 安装JDK1.6.2 配置环境变量 1.7 初始Java中main函数1.7.1 JDK、JRE、JVM之间的关系 1.8 注释1.9 标识符1.10 关键字 1. 初识java 1.1 Java是什么 Jav…

AXI-Stream协议详解(3)—— AXI4-Stream IP核原理分析

一、前言 在之前的文章中&#xff0c;我们介绍了AXI-S协议的一些基础知识&#xff0c;这是我们进行本文学习的前置基础&#xff0c;因此建议在开始本文章的学习前&#xff0c;完整阅读以下两篇文章&#xff1a; AXI-Stream协议详解&#xff08;1&#xff09;—— Introduction…

泛微OA之获取每月固定日期

文章目录 1.需求及效果1.1需求1.2效果 2. 思路3. 实现 1.需求及效果 1.1需求 需要获取每个月的7号作为需发布日期&#xff0c;需要自动填充1.2效果 自动获取每个月的七号2. 思路 1.功能并不复杂&#xff0c;可以用泛微前端自带的插入代码块的功能来实现。 2.将这需要赋值的…

Python:一个函数可以被多个装饰器装饰

理解&#xff1a; 规律&#xff1a; 一个函数可以被多个装饰器装饰. wrapper1 wrapper2 def target():print(我是目标)规则和规律 wrapper1 wrapper2 TARGET wrapper2 wrapper1def wrapper1(fn): # fn: wrapper2.innerdef inner(*args, **kwargs):print("这里是wrapper1 …

EtherCAT主站SOEM-- 0 SOEM下载编译及文件功能介绍

0 介绍EtherCAT主站SOEM文件及主要功能函数 1. soem介绍&#xff1a;2 soem主要功能文件说明&#xff1a;3 soem下载链接4 编译soem4.1 Windows (Visual Studio)&#xff1a;4.2 Linux & macOS&#xff1a; 该文档修改记录&#xff1a;总结 1. soem介绍&#xff1a; SOEM&…

BUUCTF 刮开有奖 1

这题使用IDA反汇编的话有windows编程基础会好些&#xff0c;看不懂跟着思路来也行 文章目录 一、基本分析二、代码分析第一处判断疑问 第二个判断第三处判断第四处判断第五处判断第五处判断 三、flag四、最后 一、基本分析 运行后 然后就什么都没有了 IDA反汇编 紫色颜色的函…

异常---

目录 认识异常 自定义异常 认识异常 1.异常是什么&#xff1f; 2&#xff0e;异常的代表是谁&#xff1f;分为几类&#xff1f; Error &#xff1a;代表的系统级别错误&#xff08;属于严重问题&#xff09;&#xff0c;也就是说系统一旦出现问题&#xff0c; s u n 公司会把…

RDMA概览

RDMA(Remote Direct Memory Access&#xff0c;远程直接内存访问)&#xff0c;指能够访问(读写)远程机器的内存。有多种支持RDMA的网络协议&#xff0c;包括&#xff1a;Infiniband、RoCE和iWAPP。具体的API定义包含在内核文件linux/include/rdma/ib_verbs.h reference: 【精选…

02【Git分支的使用、Git回退、还原】

上一篇&#xff1a;01【Git的基本命令、底层命令、命令原理】 下一篇&#xff1a;03【Git的协同开发、TortoiseGit、IDEA的操作Git】 文章目录 02【Git分支的使用、Git回退、还原】一、分支1.1 分支概述1.1.1 Git分支简介1.1.2 Git分支原理 1.2 创建分支1.2.1 创建普通分支1.…

如何理解my_map.yaml中origin的含义

当然可以。首先,我们先了解一下2D地图的基本构成。2D地图实际上是一个网格系统,其中每个单元格(或像素)代表现实世界中的一个区域。当我们谈论origin时,我们实际上是在描述这个网格如何在真实的3D空间中放置。 让我们通过一个简单的示意图来解释: 假设上面的矩形表示一个…

分组卷积的思想神了

大家好啊&#xff0c;我是董董灿。 最近&#xff0c;分组卷积帮我解决了一个大忙&#xff0c;事情是这样的。 这几天遇到一个头疼的问题&#xff0c;就是要在某一芯片上完成一个神经网络的适配&#xff0c;这个神经网络中卷积居多&#xff0c;并且有一些卷积的通道数很大&…

Go 命令大全:全面解析与实践

一、Go命令全列表 在这部分&#xff0c;我们将通过一个表格来快速浏览Go语言的所有内建命令及其基本功能。这些命令涵盖了从代码构建、测试&#xff0c;到依赖管理和其他工具等方面。 命令功能描述go build编译Go源文件go run编译并运行Go程序go get下载并安装依赖或项目go m…

AD9371 官方例程HDL详解之JESD204B RX侧时钟生成

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…