详解二分法查找目标值/二分法查找上下界的两种写法

详解二分查找的两种写法以及二分查找的六种变形 本文详解了二分查找的两种写法以及二分查找的六种变形。 阅读详情

本文中默认数组呈升序。

💡 绝对不能使用left = cur这种更新,由于整数除法取下界,left不更新会导致循环无法结束

寻找与target相等

  1. 可以用(l < r)写法,末尾r==l需要检查是否满足条件,满足则输出,不满足则输出-1
  2. 可以用(l<=r) 写法,末尾输出r 不需要检查是否满足条件,不满足的情况下r为-1,因此结果r可能会超出数组索引,注意不要对此进行nums[r]的检查
// ==
// Method1 : left=mid+1, right=mid, 此时最优解为最后的重合解(若可行)
// 遍历直至left = right,左右重合时退出循环,此时重合解若可行,即为答案
int BinSearch1(vector<int> &nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l < r) {
        mid = (l+r)/2;
        if (nums[mid] == target)
            return mid;
        else if (nums[mid] < target) {
            l = mid + 1;
        }
        else
            r = mid;
    }
    if (nums[r] == target)
        return r;
    return -1;
}

// ==
// Method2 : left=mid+1, right=mid-1, 此时最优解需要另外记录
// 遍历直至left > right,左右重合时仍然进入循环并进行结果记录
int BinSearch2(vector<int> &nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l <= r) {
        mid = (l+r)/2;
        if (nums[mid] == target)
            return mid;
        else if (nums[mid] < target) {
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
    return r;
}

寻找最后一个小于(等于)target

💡 需要使用(l<=r) 的写法

因为查找≤时不满足条件更新的是右界,满足条件下更新左界;

如果采用(l<r)写法:

  • 更新左界如果使用l = mid+1 ,由于mid此时满足条件,会导致新区间错失满足条件的点,答案错误
  • 如果使用l=mid,由于mid=(l+r)/2整数除法取下界,某些情况下左界会不更新,从而引起循环无法结束,程序错误

综上,在升序区间查找≤时只能采用(l≤r) 的写法,并通过r输出最终结果:若无满足条件的元素,将会使得r==-1 。

// <
int BinLBound(vector<int> &nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l <= r) {
        mid = (l+r)/2;
        // 先更新不满足条件
        if (nums[mid] >= target) {
            r = mid - 1;
        }
        else
            l = mid + 1;
    }
    return r;
}

// <=
int BinLEBound(vector<int> nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l <= r) {
        mid = (l+r)/2;
        if (nums[mid] > target)
            r = mid - 1;
        else
            l = mid + 1;
    }
    return r;
}

寻找第一个大于(等于)target

💡 需要使用(l<r) 的写法

// >
int BinHBound(vector<int> &nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l < r) {
        mid = (l+r)/2;
        if (nums[mid] <= target)
            l = mid + 1;
        else
            r = mid;
    }
    if (nums[r] > target)
        return r;
    return -1;
}
// >=
int BinHEBound(vector<int> &nums, int target) {
    int l = 0;
    int r = nums.size()-1;
    int mid;
    while (l < r) {
        mid = (l+r)/2;
        if (nums[mid] < target)
            l = mid + 1;
        else
            r = mid;
    }
    if (nums[r] >= target)
        return r;
    return -1;
}

整体测试代码

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> nums{-5, 0, 1, 2, 5, 10, 30, 90};
    int target = 90;
    cout << BinSearch1(nums, target) << " " << BinSearch2(nums, target) << endl;
    cout << BinLBound(nums, target)  << " " << BinLEBound(nums, target) << endl;
    cout << BinHBound(nums, target)  << " " << BinHEBound(nums, target);
    return 0;
}

关于二分法的边界问题及两种写法 关于二分法的边界问题及两种写法 二分查找法大家很熟悉了,对于一个有序序列,我们可以通过二分查找法在 O(logN)O(logN)O(logN) 的时间内找到想要的元素。但是,在代码实现的过程中,如果没有仔细理解清楚,二分法的边界条件有时会让人很头疼,而对边界条件的妥善处理是很能体现一个人的代码功底的,也通常是面试官会很关注的一个点。另外,大佬的题解中的二分法代码也总有几处小细节不同,但是大佬的代码都是怎么测都没问题的,自己却总因为某处细节没有处理好而出现问题。 实际上,二分法通常有两种细节略有不同的实现方式 阅读详情

相关推荐

C++算法——二分法查找

本章介绍了二分查找的算法思想,并且整理了相关的经典题目,从简单到难的去逐步递进,并且提供了链接和描述,可以直接通过链接去练习,或者直接看本篇博客去尝试思考解题,还提供了参考的思路,部分困难的题目会结合图像去分析,还有测试通过的参考代码

学习C++的小陈同学 5782

二分法(查找元素及其上界与下界)

利用二分法去查找某个元素效率高,将所要查找的元素称为key,有时利用二分法进行查找key的上界与下界,下界通常为key第一次出现的位置,上界通常为第一个大于key的位置。1 寻找元素的代码:int find(int array[], int len,int key) { int left = 0, right = len ; // attention while (left

U__F__O 1419

算法第三期——二分法(Python)

二分法:把一个长度为n的有序序列上O(n)的查找时间,优化到了O(logn)。

荷叶田田的博客 1万+

二分法

二分法 二分法的思想很简单,确定好上下界,取中间的数,看是否符合条件,若是则将下界更新为中间数后的一位。即每次循环都将当前范围分成两份,然后抛弃不符合题意的一半,显然它的时间复杂度为O(log 2n) 。它适用于较长的数组,并且数组元素必须是排好序的。 比如给出一个数组array[10]={1,2,3,4,5,6,7,8,9,10};查找数组中是否含有8,是则输出“Yes”,否则输出“No”。 首先它是排好序的,符合条件,我们使用二分法: 定义上下界分别为10和1,中间数为(1+10)/2=5,5<8

weixin_43414877的博客 389

《涨知识啦29》-DBR的工作原理及其在VCSEL中的作用

分布式布拉格(Distributed Bragg Reflection,简称DBR)反射镜是垂直腔面发射激光器(Vertical-Cavity Surface-Emitting Laser,简称VCSEL)的重要组成部分。典型的DBR反射镜是由1/4ni波长厚度的高折射率和低折射率材料交替组成(ni是该层的折射率)。其反射率取决于组成对数、边界条件以及折射率差。 图1 布拉格反射镜的工作原理 DBR反射镜的工作原理如图1所示。根据反射原理,当光从光疏介质n1射向光密介质n2(折射率n2>n1)时,反

simucal的博客 7983

别只会‘pip install’了!当Python报错找不到‘pkg_resources’时,你的setuptools可能出大问题

本文深入解析Python开发中常见的`ModuleNotFoundError: No module named 'pkg_resources'`错误,揭示其背后的setuptools依赖问题。通过系统化的诊断与修复指南,帮助开发者理解Python包管理机制,并提供从基础到高级的解决方案,确保pip和setuptools的正常运行。

weixin_42523711的博客 435

你真的理解二分的写法吗 - 二分写法详解

说实话,我之前也不完全理解二分查找的各种写法,导致在写各种二分的边界时我总是弄不清边界值,于是我只能通过暴力枚举这些边界值,去一个一个试,这样子效率真的很低下。于是,痛定思痛,一定要把二分的写法吃透,就有了这篇文章。 二分写法的种类 二分写法的种类很多,最常见的就是二分查找了的最普遍写法了。代码如下: bool bFind(int a[], int left, int right,

FlushHip 1万+

信号编辑软件ZX/SignalEditing

信号编辑软件ZX/SignalEditing

weixin_45661395的博客 958

codeforces 1075B

B. Taxi drivers and Lyft http://codeforces.com/problemset/problem/1075/B   二分查找相邻司机,比较距离后确定最终结果。   lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。返回地址减去起始地...

besti_white 582

【手把手教学】YOLOv13的Dilated Reparam Block (DRB) 实现细节与优化技巧

DRB(Dilated Reparam Block)是一种创新的卷积神经网络模块,通过多分支膨胀卷积和结构重参数化技术显著提升模型性能。训练阶段使用不同膨胀率和卷积核大小的并行分支增强特征提取能力,推理阶段则将这些分支融合为单一高效的大核卷积。该方法成功解决了大核卷积的计算复杂度和训练困难等问题,在保持推理效率的同时,使模型准确率提升8.56%,mAP暴涨12.33%。DRB的核心在于训练时复杂、推理时简单的设计哲学,以及膨胀卷积的多尺度特征提取能力,为CNN性能优化提供了新的思路。

FJN110的博客 556

西安交通大学软件学院——分布式系统练习题(综合题)

摘要:本文探讨了分布式系统的核心特性与关键问题。首先阐述了分布式系统的8种透明性特性,包括访问、定位、迁移等。然后通过具体案例分析了分布式事务的回滚机制、域名解析的迭代与递归过程、不同分布式系统的异同比较。重点讨论了RPC通信中客户端/服务器崩溃的处理方法,包括消灭、再生和到期三种策略。最后介绍了Lamport时间戳算法在进程通信中的应用及问题解决方案。全文涵盖了分布式系统设计中的透明性、可靠性、一致性等核心问题。

qq_73044452的博客 204

二分查找详解

目录 1.简介 2. 例子 3. 第一种写法(左闭右闭) 3.1 正向写法(正确演示) 3.2 反向写法(错误演示) 4. 第二种写法(左闭右开) 4.1 正向写法(正确演示) 4.2 反向写法(错误演示) 5. 总结 写在前面: 主要解释了二分法的左闭右闭区间,左闭右开区间两种写法,并且每个写法都举了相应的反例,范围写错的话可能会出现的错误等… 1.简介 有一天小明到图书馆借了 N 本书,出图书馆的时候,警报响了,于是保安把小明拦下,要检查一下哪本书没有登记出借。小明正

m0_49264693的博客 8867

ThingsBoard教程(一):ThingBoard介绍及安装

ThingsBoard介绍 最近看了很多开源的物联网的项目,其中有一个让我印象很深,那就是Thingsboard 下面我就给大家介绍一下这个项目,并指导大家如何在本地安装一个Thingsboard来体验它。 首先引用官网的项目介绍就是 一个开源的用于数据收集,处理,可视化和设备管理的开源物联网平台。 它通过行业标准的物联网协议(MQTT,CoAP和HTTP)实现设备连接,并支持云和本地部署。ThingsBoard结合了可伸缩性,容错性和性能,因此您永远不会丢失数据。 用它开源收集链接设备,收集设备的数据,

知无涯 2万+

【二分查找】详细图解

二分查找 文章目录二分查找1. 简介2. 例子3. 第一种写法(左闭右闭)3.1 正向写法(正确演示)3.2 反向写法(错误演示)4. 第二种写法(左闭右开)4.1 正向写法(正确演示)4.2 反向写法(错误演示)5. 总结 写在前面: (一)二分法的思想十分容易理解,但是二分法边界处理问题大多数人都是记忆模板,忘记模板后处理边界就一团乱(????:“我懂了”, ✋ :"你懂个????"​)因为我此前也是记忆模板,所以现在想通过一边学习,一边将所学记录成博客教出去(费曼学习法),希望以后能自己推导出边界如

Charon的博客 28万+

YOLO26涨点改进| TGRS 2026 | 独家创新首发、注意力改进篇| 引入CSSCA频谱-空间交叉注意力,含多种创新改进,小目标检测、图像分割、高光谱图像分类、语义分割任务任务涨点

🔥本文提出CSSCA(频谱-空间交叉注意力)模块,通过中心像素引导的光谱与空间交叉注意力机制,有效提升YOLO26模型的特征表达能力。该模块实现了光谱与空间信息的协同优化,能够自适应强化关键通道与重要空间区域,增强模型对小目标和复杂场景的感知能力。文章详细介绍了CSSCA的网络结构、工作原理及四大优势,包括精准特征表达、协同信息优化、小样本适应性和轻量化设计。同时提供了完整的代码实现和四种改进方案的YAML配置文件,包括基础版、增强版、C3k2融合版和C2PSA融合版,为YOLO26模型的性能提升

Ai缝合怪、助力小伙伴高效发论文 268

【网络安全 | 渗透工具】Githack工具安装及使用教程详析

本文仅分享Githack工具基本安装及使用相关知识不承担任何法律责任。Git是一个非常流行的开源分布式版本控制系统,它被广泛用于协同开发和代码管理。许多网站和应用程序都使用Git作为其代码管理系统,并将其部署到生产环境中以维护其代码库。然而,在配置不当的情况下,可能会导致.git文件夹被直接部署到线上环境中,这可能会导致Git泄露问题。可通过githack下载泄露的Git存储库,以获取包含未加密密码、凭据和敏感信息的站点代码库。使用githack下载Git存储库的方法有两种。本文仅分享。

等风来 3万+

二分法题型小结

在刷题的过程中,二分法用的还是挺多的,有时候超时了往往是你没有用上二分法,今天我就来稍微总结下用的最多的三种二分法搜索。 一、搜索和目标值相等的数 这一类是最简单的,例如对于数组 arr = {1, 2, 5, 6, 9},要我们搜索返回目标数 target = 6,这个时候我们需要返回 6 的下标 i = 3。代码如下 int binarySearch(int[] arr, int target...

帅地 3115

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

力扣.34以及二分法两种方法的区别

我也是一开始想不明白为什么左闭右开区间,right指向middle的下标,所以我写了这篇博客,后面我发现,在第二种方法下,如果right=middle,可能会错过target.这样只是我个人的看法,我在b站up代码随想录中找到了答案当nums[middle]>traget时,说明traget在数组的左区间(递增数组中),traget所在的左区间,是不包括右边界的(前面我们说查找区间是个左闭右开),而nums[middle]也不等于traget,所以right是可以等于middle的.

qq_62035394的博客 1228

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

二分法保姆级教学(看不懂来砍我)

首先看一个例子如果你瞎猜(1、2、3... 依次试),运气差可能要猜 100 次。但聪明的办法是先猜 50:如果我说「大了」,就知道答案在 1-49 之间;如果我说「小了」,就知道在 51-100 之间。每次都把范围砍一半,最多 7 次就能猜到(这就是「二分法」)所以不难看出二分法中间是把大的搜索范围通过序的关系给减少。所以这也就引出了二分法的前提条件:有序且无重复元素那么来看一个例子。

2301_79524309的博客 3594

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

二分法的两种写法(整理的乱七八糟的)

二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right) 二分法第一种写法 我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right]。 区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点: while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <= if (nums[middle] >

duoduohair的博客 771

面试题之二分法查找详解

前言 回顾以往面试中,算法提到最多的就是二分法了,感觉简单,但是突然提到又难以入味,所以本文将整理总结出最简单的理论和程序实践,结合实际面试题来解答! 二分法概念 二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。 二分法查找的思路如下: 1.首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。 2、如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。 3. 如果某一步数组为空,则表示找不到目标元素。

波风水门 2302

二分法查找

一、二分法思想 二分法查找针对的是一个有序的数据集合,每次通过与区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为0. 故时间复杂度就是O(logn) 二分查找的递归与非递归实现 ...

sinat_31608641的博客 2628

二分查找的两种写法

二分查找的两种写法

m0_46378271的博客 305

二分法在搜索插入位置中不同写法的分析

探讨究竟是left < right还是left <= right前言二分法简介分析例题两种二分法区别分析结语 前言 最近复习C++,看到一篇很好的介绍二分法的文章,这里分享一下: just click me 文中提到了二分法的两种写法,我在此想分享一下我的分析~ 二分法简介 当我们想在一个有序数组中查找某一个值target时,我们可以直接将target与数组中间的值比较大小,根据比较的结果,我们可以直接过滤掉一半的数据,二分法就是不断重复这一过程,试图找到一个与target相等的值的算法。 分析

qq_43747034的博客 205

代码随想录二刷复习(二分法)

第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

qq_44219883的博客 1128

[leetcode 1095] 山脉数组中查找目标值

山脉数组中查找目标值分析思路找到山顶位置山底到山顶 递增区间二分查找山顶道山底 递减区间二分查找源码 分析 首先可以看到这是一个山脉,他的大体结构类似于一个上山和一个下山的过程,上山是一个递增数组,下山是一个递减数组,如下图。。。。 其次,题中明确说明了,访问数组元素的下标次数不能多于100次,但是数组长度最大为10000,所以说我们用变量肯定是不行的。 这时就可以使用二分法了,...

duchenlong的博客 394
上一篇: gcc编译ld报错multiple definition of `_IO_std_used`
你们EE出了个傻子
博客等级 码龄10年 29粉丝 19原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值