算法-二分专题

文章目录

  • 概念
  • 应用场景
  • 代码模板
  • OJ练习
    • 寻找指定元素1
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解
    • 寻找指定元素2
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解
    • 寻找指定元素3
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解
    • 寻找指定元素4
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解
    • 寻找指定元素5
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解
    • 寻找指定元素6
      • 题目描述
      • 输入描述
      • 输出描述
      • 样例
      • 题解

概念

二分查找(Binary Search)算法,也叫折半查找算法。二分查找的思想非常简单,有点类似分治的思想。二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。

为了方便理解,我们以数组

1,3,5,7,11,13,17,19,23,29,31,37,41,43,53,59,在数组中查找37为例,制作了一张查找过程动图,其中low标示左下标,high标示右下标,mid标示中间值下标
在这里插入图片描述
可以看出二分查找在查找数字 37 时只需3次,而顺序查找 查找37时需要11次。

应用场景

二分搜索用于在一个单调或者局部单调有序数组中查找一个符合某些条件的值,时间复杂度为O(logN)

代码模板

int BinarySearch(int *a,int len,int key){int low = 0,high = len-1,mid;while(low<=high){mid = (low+high)/2;      //取中间位置if(a[mid] == key){return mid;          //查找成功并返回所在位置}else if( key < a[mid] ){   high = mid - 1;	     //从前半部分查找}else{low = mid + 1;	     //从后半部分查找}}
}

OJ练习

寻找指定元素1

题目描述

在一个严格递增序列A中寻找一个指定元素x,如果能找到,那么输出它的下标;如果不能找到,那么输出。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

如果能找到x,那么输出它的下标;否则输出-1。

样例

样例1

输入

5 3
1 2 3 5 8

输出

2

样例2

输入

5 6
1 2 3 5 8

输出

-1

题解

这题就是直接套模板

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len-1,mid;while(low<=high){mid = (low+high)/2;      //取中间位置if(a[mid] == key){return mid;          //查找成功并返回所在位置}else if( key < a[mid] ){   high = mid - 1;	     //从前半部分查找}else{low = mid + 1;	     //从后半部分查找}}return -1;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

寻找指定元素2

题目描述

在一个严格递减序列A中寻找一个指定元素x,如果能找到,那么输出它的下标;如果不能找到,那么输出-1。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

如果能找到x,那么输出它的下标;否则输出-1。

样例

样例1

输入

5 3
8 5 3 2 1

输出

2

样例2

输入

5 6
8 5 3 2 1

输出

-1

题解

这个就是在板子基础上,把大于号小于反过来就行了,递增变递减

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len-1,mid;while(low<=high){mid = (low+high)/2;      //取中间位置if(a[mid] == key){return mid;          //查找成功并返回所在位置}else if( key > a[mid] ){   high = mid - 1;	     //从前半部分查找}else{low = mid + 1;	     //从后半部分查找}}return -1;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

寻找指定元素3

题目描述

在一个递增序列A(可能存在重复元素)中寻找第一个大于等于x的序列下标。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

输出第一个大于等于x的序列下标。

样例

样例1

输入

5 5
1 4 5 5 7

输出

2

解释

序列中存在5,所以第一个大于等于5的元素就是5,对应的序列下标是2

样例2

输入

5 6
1 4 5 5 7

输出

4

解释

序列中不存在6,第一个大于等于6的元素是7,对应的序列下标是4

样例3

输入

5 8
1 4 5 5 7

输出

5

解释
序列中所有元素都小于8,因此第一个大于等于8的序列下标是5

题解

循环条件为low<high而非之前的low<=high,这是由问题本身决定的。在上一个问题中,需要当元素不存在时返回-1,这样当low>high时[low,high]这个区间就不存在了,可以此作为元素不存在的判定原则,因此low<=high满足时循环应当一致执行;但是如果想要返回第一个大于等于x的元素的位置,就不需要判断x本身是否存在,因为就算它不存在,返回的也是“假设它存在,它应该在的位置”,于是当low==high时,[low,high]刚好能夹出唯一的位置,就是需要的结果,因此只需要当low<high时让循环一直执行即可。

由于当low==high时while循环停止,因此最后的返回值既可以是low,也可以是high。

二分的初始区间应当能覆盖到所有可能返回的结果。首先,二分下界是0是显然的,但是二分上界是n-1还是n呢?考虑到要查询元素有可能比序列中的所有元素都要大,此时应当返回n(即假设它存在,它应该在的位置),因此二分上界是n,故二分的初始区间为[low,high]=[0,n]

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len;while(low<high){int mid = (low+high)/2;      if(a[mid] >= key){high = mid;         }else{   low = mid + 1;	     }}return low;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

寻找指定元素4

题目描述

在一个递增序列A(可能存在重复元素)中寻找第一个大于x的序列下标。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

输出第一个大于x的序列下标。

样例

样例1

输入

5 5
1 4 5 5 7

输出

4

解释

序列中存在5,所以第一个大于等于5的元素就是5,对应的序列下标是2

样例2

输入

5 6
1 4 5 5 7

输出

4

解释

序列中不存在6,第一个大于等于6的元素是7,对应的序列下标是4

样例3

输入

5 8
1 4 5 5 7

输出

5

解释
序列中所有元素都小于8,因此第一个大于等于8的序列下标是5

题解

此题和上题类似,只需要把等于号去掉

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len;while(low<high){int mid = (low+high)/2;      if(a[mid] > key){high = mid;         }else{   low = mid + 1;	     }}return low;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

寻找指定元素5

题目描述

在一个递增序列
A(可能存在重复元素)中寻找一个指定元素x,如果能找到,那么输出第一个x的下标;如果不能找到,那么输出-1。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

如果能找到x,那么输出第一个x的下标;否则输出-1。

样例

样例1

输入

5 5
1 5 5 5 7

输出

1

解释

序列中存在三个5,第一个5的序列下标是1

样例2

输入

5 6
1 5 5 5 7

输出

-1

解释

序列中不存在6,因此输出-1

题解

因为会有很多个重复数据,这里只要出现的第一个,那么我们可以改变二分时候查找到key的条件,我们现在不让他查找到就结束,如果查找到了,就让他往左缩短,因为要找的是第一个,如果找最后一个就往右缩短就行了。

需要注意的是,如果没有查找到key,我们需要额外一个bool类型变量,用来判断是否找到过,找到过那个位置就是high+1.没找到就返回-1,可以用三目运算符实现。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
bool isFound = false;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len-1;while(low<=high){int mid = (low+high)/2;      if(a[mid] == key){high = mid-1;     isFound = true;    }else if( key < a[mid] ){   high = mid - 1;	    }else{low = mid + 1;	   }}return isFound==true?high+1:-1;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

寻找指定元素6

题目描述

在一个递增序列A(可能存在重复元素)中寻找一个指定元素x,如果能找到,那么输出最后一个x的下标;如果不能找到,那么输出-1。

注:使用二分法实现。

输入描述

在这里插入图片描述

输出描述

如果能找到x,那么输出最后一个x的下标;否则输出-1。

样例

样例1

输入

5 5
1 5 5 5 7

输出

3

解释

序列中存在三个5,最后一个5的序列下标是3

样例2

输入

5 6
1 5 5 5 7

输出

-1

解释

序列中不存在6,因此输出-1

题解

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
bool isFound = false;
int A[N];int BinarySearch(int *a,int len,int key){int low = 0,high = len-1;while(low<=high){int mid = (low+high)/2;      if(a[mid] == key){low = mid+1;     isFound = true;    }else if( key < a[mid] ){   high = mid - 1;	    }else{low = mid + 1;	   }}return isFound==true?low-1:-1;
}int main(){int n,x;cin >> n >> x;for(int i = 0;i < n;i ++){cin >> A[i];}cout << BinarySearch(A,n,x);return 0;
}

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

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

相关文章

Qt添加资源文件

ui->setupUi(this);//1. 使用本地文件&#xff1a;ui->actionasdasdas->setIcon(QIcon("本地绝对路径"));ui->actiona1->setIcon(QIcon("C:/Users/满满/Desktop/output/picture/1.jpg"));//2. 使用资源文件&#xff1a;ui->actionasdasd…

内 存 取 证

1.用户密码 从内存中获取到用户admin的密码并且破解密码&#xff0c;以Flag{admin,password}形式提交(密码为6位)&#xff1b; 1&#xff09;查看帮助 -h ./volatility_2.6_lin64_standalone -h 2&#xff09;获取内存镜像文件的信息 imageinfo ./volatility_2.6_lin64_stand…

自动化测试数据校验神器!

在做接口自动化测试时&#xff0c;经常需要从接口响应返回体中提取指定数据进行断言校验。 今天给大家推荐一款json数据提取神器: jsonpath jsonpath和常规的json有哪些区别呢&#xff1f;在Python中&#xff0c;json是用于处理JSON数据的内置模块&#xff0c;而jsonpath是用…

LLaMA-Factory添加adalora

感谢https://github.com/tsingcoo/LLaMA-Efficient-Tuning/commit/f3a532f56b4aa7d4200f24d93fade4b2c9042736和https://github.com/huggingface/peft/issues/432的帮助。 在LLaMA-Factory中添加adalora 1. 修改src/llmtuner/hparams/finetuning_args.py代码 在FinetuningArg…

【Leetcode】2085. 统计出现过一次的公共字符串

文章目录 题目思路代码 题目 2085. 统计出现过一次的公共字符串 思路 使用两个哈希表 words1Count 和 words2Count 分别统计两个数组中每个单词的出现次数。然后遍历 words1Count 中的每个单词&#xff0c;如果该单词在 words1 中出现了一次&#xff0c;且在 words2 中也出…

小红书年终“礼物营销”玩法:种拔一体,实现品效破圈

恰逢年末&#xff0c;用户送礼需求旺盛&#xff0c;小红书推出“礼物季”&#xff0c;品牌们纷纷入局&#xff0c;话题上线18天浏览量破9亿。“礼物营销”覆盖全年营销节点&#xff0c;贯穿始终&#xff0c;礼赠场景下用户消费决策链路缩短&#xff0c;种拔一体&#xff0c;帮助…

Android 集成firebase 推送(FCM)

1&#xff0c;集成firebase 基础 1>googleService文件 2>项目级gradle 3>app级gradle 4>setting 2&#xff0c;推送相关 重点&#xff1a; 源文档&#xff1a;设置 Firebase Cloud Messaging 客户端应用 (Android) (google.com) /*** 监听推送的消息* 三种情况…

el-tree多个树进行节点同步联动(完整版)

2024.1.11今天我学习了如何对多个el-tree树进行相同节点的联动效果&#xff0c;如图&#xff1a; 这边有两棵树&#xff0c;我们发现第一个树和第二个树之间会有重复的指标&#xff0c;当我们选中第一个树的指标&#xff0c;我们希望第二个树如果也有重复的指标也能进行勾选上&…

Qt 调试体统输出报警声

文章目录 前言一、方法1 使用 Qsound1.添加都文件 直接报错2.解决这个错误 添加 QT multimedia3. 加入代码又遇到新的错误小结 二、第二种方法1.引入库 总结 前言 遇到一个需求&#xff0c;使用Qt输出报警声&#xff0c;于是试一试能调用的方法。 一、方法1 使用 Qsound 1.…

什么是金融RPA?金融RPA解决什么问题?金融RPA实施难点在哪里?

什么是金融RPA&#xff1f;金融RPA&#xff0c;即金融领域的机器人流程自动化&#xff0c;是一种利用软件机器人来代替人工完成重复性劳动任务的技术。它能够通过模仿最终用户在电脑上的手动操作方式&#xff0c;实现自动化处理大量重复、规则明确的业务流程&#xff0c;如账务…

44-js return返回值,全局作用域,局部作用域,隐式作用域,变量的生命周期,delete释放内存

1.return返回值:函数执行后剩下结果就是返回值。 function fn(a,b,c){//return返回值return(a+b+c);// console.log("aaa"); //return之后的值都不在执行了// alert("bbb"); //return之后的值不在执行了}console.log(fn(1,2,3)*10); 2.作用…

低静态功耗的音频功率放大器D7368GS,适用于便携式立体声收录机应用

D7368是专为便携式立体声收录机而设计的音频功率放大器集成电路。 主要特点&#xff1a; ● 低静态功耗&#xff1a; Icco6 6mA(Typ) (Vcc6V) ● 电压增益高&#xff1a;40dB ( 典型值)。 ● 工作电源电压范围宽&#xff1a;Vcc2~10V. . ● 外围使用元件少( 仅需三个电容)。 ●…

软件测试|如何在Linux中下载和安装软件包

简介 在Linux操作系统中&#xff0c;下载和安装软件包是一项基本任务。不同的Linux发行版可能有不同的包管理工具和方式&#xff0c;但总体流程是类似的。以下是在Linux中下载和安装软件包的详细步骤。 步骤1&#xff1a;选择适当的包管理工具 因为Linux有不同的发行版本&am…

活动回顾∣“全邻友好,艺术大咖交流会”——员村街开展社区微型养老博览会长者文艺汇演活动

为进一步营造邻里守望&#xff0c;共建美好社区的氛围&#xff0c;促进社区长者参与社区服务&#xff0c;展示社区长者健康、积极向上的精神风貌&#xff0c;2024年1月10日&#xff0c;员村街开展“全邻友好&#xff0c;艺术大咖交流会”——微型养老博览会活动&#xff0c;让长…

Docker安装Redis 配置文件映射以及密码设置

安装直接docker pull redis即可&#xff0c;默认redis最新版 设置两个配置文件路径 mkdir -p /root/docker/redis/data mkdir -p /root/docker/redis/conf touch redis.conf // 容器挂载用conf配置文件 bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout…

轴组【CAN】

如果有126个轴&#xff0c;你程序里挨个添加轴很麻烦。 可以用轴组批量添加。【数组】 CAN驱动器 0x164 就是下个驱动器 p_CAN主站地址:ADR(IoConfig_Globals.CANopen_Manager_SoftMotion);p_CAN从站地址1:ADR(IoConfig_Globals.DMA882_CAN);p_CAN从站地址2:ADR(IoConfig_Gl…

Swin Transformer 学习笔记(附代码)

论文地址&#xff1a;https://arxiv.org/pdf/2103.14030.pdf 代码地址&#xff1a; GitHub - microsoft/Swin-Transformer: This is an official implementation for "Swin Transformer: Hierarchical Vision Transformer using Shifted Windows". 1.是什么&#x…

libignition-gazebo-diff-drive-system.so是什么

因该就是个动态链接库&#xff0c;库文件之类 而且就是gazebo6版本也就是ign 这个版本的动态链接库有个特点&#xff1a;全部都是以.so结尾&#xff0c;所以很可能ign的插件plugin都是带.so的 abcdegx.so elvikorflsd.so fvlwirjgiojf.so等

Android可换行的RadioGroup

Android可换行的RadioGroup,有时候需要换行显示的单选列表&#xff0c;当然可以有多种实现方式&#xff0c;比如recycleview或者listview实现&#xff0c;本文采用的是RadioGrouprediobutton方式实现。 一、首先自定义view public class WrapRadioGroup extends RadioGroup {pr…

经典算法-模拟退火算法求解旅行商问题TSP

经典算法-模拟退火算法求解旅行商问题TSP 旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;是组合优化中的经典问题。简单地说&#xff0c;一个旅行商需要访问N个城市&#xff0c;并返回到出发城市&#xff0c;问题是找到最短的可能路线&#xff0c;使得每…