二分查找知识点及练习题

知识点讲解

一、没有相同元素查找

请在一个有序递增数组中(不存在相同元素),采用二分查找,找出值x的位置,如果x在数组中不存在,请输出-1!

 输入格式

 第一行,一个整数n,代表数组元素个数(n <= 600000)

第二行,n个数,代表数组的n个递增元素(1<=数组元素值<=2000000)

 第三行,一个整数x,代表要查找的数(0<=x<=2000000)

输出格式

按题意输出位置或者-1。

输入/输出例子1

输入:

10

1 3 5 7 9 11 13 15 17 19

3

输出:

2

【分析】:当我们要从一个序列中查找一个元素的时候,最快想到的方法就是顺序查找法(即:从前到后依次查找)。但这种方法过于无脑,就是暴力的把每个元素都排查一遍。元素个数少的时候还行,一旦元素个数多起来,效率非常低下。

分查找法也称折半查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log2n)完成查找任务。

它的基本思想是,先把n个元素从小到大排序,然后取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如果x<a[n/2],则我们只要在数组a的左半部分继续搜索x。如果x>a[n/2],则我们只要在数组a的右半部分继续搜索x,直到查找成功或查找完毕为止。

以下是二分查找的查找过程图示:

12.jpg

23.jpg

二分查找的算法框架一如下:

left=1;right=n;while(left<=right){mid=(left+right) / 2;if (x==a[mid]){ printf("%d",mid)}//查找成功,输出mid的值并结束;if (x>a[mid]) left=mid+1;//往数组的右边找if (x<a[mid]) right=mid-1;//往数组的左边找}
printf("查找不成功")//输出“查找不成功”

在查找过程中我们每次把查找的范围缩小了一半,在最坏情况下查找log2n次就可以得到结果。

注意:

1.二分查找是在数据有序的情况下才能完成,即进行二分查找前数据必须先排序。上述框架是以数据已从小到大排序为前提条件的。

2.这里可能解的范围为[left,rigth],当x>a[mid]时,x如果存在的话应该是在数组的[mid+1,right]中,此时的left改为mid+1,而不是mid;同理,当x<a[mid]时,x如果存在的话应该在数组的[left,mid-1]里,此时的right应该改为mid-1,而不是mid。

41.png

42.png

43.png

二分查找的算法框架二如下:

left=0;right=n+1;while(left+1<right){mid=(left+right) / 2;if (x==a[mid]){ printf("%d",mid);}//查找成功,输出mid的值并结束;if (x>a[mid]) left=mid;//往数组的右边找if (x<a[mid]) right=mid;//往数组的左边找}printf("查找不成功");//输出“查找不成功”

二、有相同元素的查找

1、求左侧边界:

这样就引申出一个问题:如何二分查找求左侧边界。当查找的数字v存在时,得到它出现的第一个位置,假如不存在,就得到比它大的第一个数的位置。

这样只要把二分查找修改一下:

为了查找方便,我们在数组a[0]处插入一个最小的数-1,在a[n+1]处插入一个无穷大数,left指向0,right指向n+1,这样解空间为(left,right]。

1、 情况a[mid]>=v时:right=mid(至少已经找到一个,或者mid可能已经是比v大的数中最小的一个,或者左边可能还有比v大的,因此区间变成(left,mid]。)

2、 情况a[mid]<v时;left=mid,也就是解只可能在右边。

例如:

-1 2 3 5 6 7 7 8  10000000 中查找v=7

第一轮:left=0,right=9,解空间为(0,9]那么mid=(0+9)/2=4,因为a[4]=6<7,那么left=mid=4,解空间应该是(4,9]。

第二轮left=4,right=9, mid=(4+9)/2=6 ,因为a[6]=7==7,那么right=6,也就是解空间为(4,6]。

第三轮 left=4,right=6, mid=(4+6)/2=5 ,因为a[5]=7==7,那么right=5,也就是解空间为(4,5]。

因为解空间只有一个解,所以解为下标5,所以left+1==right为程序结束条件。

【求下界核心程序如下】:

a[n+1]=1000000000;a[0]=-1;int findleft(int left,int right,int value)//调用时left=0,right=n+1{while(left+1<right)  //如果解区间不止一个,那么继续二分{int mid=(left+right)/2;  //取中间值if(a[mid]>=value)//如果找到一个等于或者大于value的数,解空间为(left,mid]right=mid;elseleft=mid; //如果找到一个小于value的数,解空间为(mid,right]}return right;}

2、求右侧边界

如何二分查找求右侧边界。当查找的数字v存在时,得到比它大的第一个数的位置。

方法如下:

为了查找方便,我们在数组a[0]处插入一个最小的数-1,在a[n+1]处插入一个无穷大数,left指向0,right指向n+1,这样解空间为(left,right]。

1、 情况a[mid]>v时:right=mid(至少已经找到一个,或者mid可能已经是比v大的数中最小的一个,或者而左边可能还有比v大的,因此区间变成(left,mid]。)

2、 情况a[mid]<=v时;left=mid,也就是解只可能在右边。

【求上界核心程序如下】:

a[n+1]=1000000000;a[0]=-1;int findright(int left,int right,int value)//调用时left=0,right=n+1{while(left+1<right) //如果解区间不止一个,那么继续二分查找{int mid=(left+right)/2;if(a[mid]<=value)//找到一个小于或者等于value的数,解空间为(mid,right)left=mid;elseright=mid; //如果找到一个大于value的数,解空间为(left,mid)}return right;}

拓展:另外一种二分查找形式找左侧和右侧:

根据c++的整除是求下界,那么两个相邻的数求平均数等于较小的数,也就是当求区间解时,当左区间不能满足要求时,可以让left=mid+1,跳出条件变为L<R,也就是解空间为(L,R]。

找左侧核心程序如下:

int L=0,R=n+1,mid;while(L<R){mid=(L+R)/2;if(a[mid]<x)L=mid+1;elseR=mid;}if(a[R]==x) printf("%d ",R);else printf("-1 ");

找右侧核心程序如下:

int L=1,R=n+1,mid;while(L<R){mid=(L+R)/2;if(a[mid]<= x)L=mid+1;elseR=mid;}if(a[L-1]==x) printf("%d ",L-1);else printf("-1 ");

讲完知识点,我们来看看几道习题

习题部分

进击的河流

有一个铁人三项运动员,他的弱点是就是游泳,正好他家旁边有n条流速不同的河流,他想锻炼m天。
在这m天中,他每天都有不同的体力,他只能在流速小于他体力的河流里游,不然他就会被冲到太平洋(?!!!!!!)。
他想知道每天他能在多少条河里游泳。

输入格式

第一行:n(n<=10^6)

第二行:n个数,分别表示n条河流的流速

第三行:m(m<=10^6)

接下来有m行,分别表示m天中运动员不同的体力

输出格式

m行,分别表示运动员m天里每天他能在多少条河里游泳

输入/输出例子

输入:

10
1 1 1 2 2 2 2 3 4 4
5
3
2
5
4
1

输出:

7
3
10
8
0

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,a[10000005],x;
int main(){cin>>n;for(int i=1;i<=n;i++)scanf("%d",&a[i]);cin>>k;while(k--){scanf("%d",&x);int l=0,r=n+1,m=0;while(l+1<r){m=(l+r)/2;if(a[m]<x)l=m;else r=m;}cout<<r-1<<"\n";}return 0;
}

 生死狙击

小飞最近迷上了一个叫生死狙击的游戏。不过他的技术并不好,假设他的战斗力是•x。不过,他的战斗力是由心情来定的,每天都不同。现有一群(1<=n<=100000)也是玩生死狙击的朋友,他们也有战斗力。小飞想找一些比自己强的人玩,提高自己的战斗力,如:小烨,小祖,小明等。
小飞一共玩了m天,假设其他人的战斗力不变。问:小飞每天可以找到多少比自己强的人。

输入格式

第一行输入一个n,表示有n个朋友;(1<=n<=100000)
第二行输入n个朋友的战斗力;每个朋友战斗力不超过longint;(已有序);
第三行输入一个m,表示有m天;(1<=m<=100000)
接下来m行,表示小飞每天的战斗力;小飞战斗力不超过longint;

输出格式

共m行,每一行小飞每天找到的人数;

输入/输出例子

输入:

5
1 1 3 5 5
3
0
2
5

输出:

5
3
0
代码:
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[10000005],x;
int main(){cin>>n;for(int i=1;i<=n;i++)scanf("%lld",&a[i]);cin>>k;while(k--){scanf("%lld",&x);long long l=0,r=n+1;while(l+1<r){long long m=(l+r)/2;if(x>=a[m])l=m;else r=m;}printf("%lld\n",n-r+1);}return 0;
}

选人

在一条坐标轴上,有N头奶牛,第i头奶牛的位置是Xi。FJ现在要选出三头奶牛去比赛,不妨假设选择了奶牛a,b,c。那么必须要满足:

1、Xa < Xb < Xc。

2、 Xb-Xa <= Xc - Xb <= 2 * (Xb - Xa)。

你的任务是计算,FJ总共有多少种不同的选择?

输入格式

第一行,一个整数N。 3 <= N <= 1000。 接下来有N行,第i行是整数Xi。

输出格式

一个整数。

输入/输出例子

输入:

5 
3 
1 
10 
7 
4

输出:

4

样例解释

可以有4种不同的选择,每种选择对应的3头奶牛的坐标是: {1,3,7} {1,4,7} {4,7,10} {1,4,10}

代码:
#include<bits/stdc++.h>
using namespace std;
long long n,s,q[10000000],t,m,ans,ans2,l,r;
int main()
{scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&q[i]);sort(q+1,q+1+n);for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){int l=0,r=n+1,m;while(l+1<r){m=(l+r)/2;if(q[j]-q[i]>q[m]-q[j])l=m;else r=m;}ans=l;l=0,r=n+1;while(l+1<r){m=(l+r)/2;if(q[m]-q[j]>2*(q[j]-q[i]))r=m;else l=m;}ans2=l;t+=ans2-ans;}}cout<<t;return 0;
}

能不能留下关注和点赞........

安慰一下啥也不会的小学生..........

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

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

相关文章

家用洗地机买什么牌子的好?四大业内顶尖品牌推荐

家庭清洁一直是必不可少的&#xff0c;但用传统的手动拖地清洁&#xff0c;费时又费力。现在出现了洗地机&#xff0c;确实改变了我们对家庭清洁的看法。它不仅能扫地、拖地&#xff0c;还能吸水&#xff0c;甚至能够自动清洁滚刷解放我们双手&#xff0c;提供高效清洁的同时还…

【Linux系列】 离线安装vnc 可视化桌面

离线安装vnc 可视化桌面 缘下载安装vnc初始化链接 缘 项目需要下载 下载地址&#xff1a; http://mirror.centos.org/centos/7/updates/x86_64/Packages/tigervnc-license-1.8.0-31.el7_9.noarch.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/libXfont2-2.0.…

【Day 6】MySQL 基础

1 MySQL DataBase&#xff08;DB&#xff09;是存储和管理数据的仓库 DataBaseManagementSystem&#xff08;DBMS&#xff09;数据库管理系统&#xff0c;操纵和管理数据库的大型软件 SOL&#xff08;Structured QueryLanguage&#xff09;操作关系型数据库的编程语言&#…

C++/Qt 小知识记录5

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识5 Windows下查看端口占用情况C调用Python三方库测试库有没有被加上的测试方法初始化使用Python的env环境&#xff0c;用Py_SetPythonHome设置GDAL相关的&#xff0c;需要把osgeo、rasterio的路径加入…

【iOS开发】(一)2024 从一无所有开始,到ios开发(react Native)

​ 2024 从一无所有开始&#xff0c;到ios开发&#xff08;react Native&#xff09; 目录标题 1 工具简介2 基础环境搭建1 安装 brew2 安装 Node.js3 安装 Yarn4 安装 React Native 脚手架 3 ios环境搭建4创建并启动一个app 在这里插入图片描述 1 工具简介 Homebrew (brew)&a…

OpenHarmony实战开发-页面布局检查器ArkUI Inspector使用指导

DevEco Studio内置ArkUI Inspector工具&#xff0c;开发者可以使用ArkUI Inspector&#xff0c;在DevEco Studio上查看应用在真机上的UI显示效果。利用ArkUI Inspector工具&#xff0c;开发者可以快速定位布局问题或其他UI相关问题&#xff0c;同时也可以观察和了解不同组件之间…

Matlab分段微分方程组拟合【案例源码+视频教程】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

LLM 构建Data Multi-Agents 赋能数据分析平台的实践之③:数据分析之一(智能报表)

概述 在企业数字化转型的过程中&#xff0c;ERP系统与数据平台作为核心支撑工具&#xff0c;对于提升运营效率、优化决策支持、实现业务流程一体化起着至关重要的作用。然而&#xff0c;智能报表与报表的智能化合并作为其中的重要领域&#xff0c;却往往面临诸多挑战与难点&am…

探索 去中心化的Web3.0

随着区块链技术的日益成熟和普及&#xff0c;Web3&#xff08;Web 3.0&#xff09;已经成为一个无法忽视的趋势。Web3不仅仅是一个技术概念&#xff0c;更是一个去中心化、透明、用户数据拥有权归还给用户的互联网新时代。在这篇文章中&#xff0c;我们将深入探讨Web3技术的核心…

纯js图片上传插件

目录标题 一、效果预览二、使用简单三、完整代码&#xff08;一&#xff09;index.html&#xff08;二&#xff09;css&#xff08;三&#xff09;js四、附带后台上传文件代码 一、效果预览 支持多图片上传&#xff0c;删除、预览。 二、使用简单 导入依赖&#xff08;需要…

Dart基础语法

Hello Dart Dart 语言与其他许多编程语言一样&#xff0c;以 main 函数作为程序的入口点。以下是一个简单的 "Hello Dart" 程序示例&#xff0c;展示了 Dart 语言的这一特点。 // 标准写法 void main(){print("Hello Dart"); }// 省略写法 main(){print(&…

WebGL绘制和变换三角形

1、绘制多个点 构建三维模型的基本单位是三角形。不管三维模型的形状多么复杂&#xff0c;其基本组成部分都是三角形&#xff0c;只不过复杂的模型由更多的三角形构成而已。 gl.vertexAttrib3f()一次只能向顶点着色器传入一个顶点&#xff0c;而绘制三角形、矩形和立方体等&am…

【网络安全】HTTP协议 — 特点

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 学习目标​ 一、请求与响应 1.服务器和客户端 二、不保存状态 1.不保存状态的协议 三、资源定位 1.URI&#xff08;统一资源标识符&#xff09; 四、请求方法 1.请求方法 五…

如何在window系统中安装Mysql

先简单来说说MySQL是什么&#xff1f; MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系统)应用软件之一。 MySQL 由瑞典 MySQL AB 公司开发&#xff0c;目前属于…

多模态模型训练QA

Q&#xff1a;InternLM-XComposer的最新版本把vit的参数量降低了但是效果好了&#xff0c;所以好奇scale up vision encoder的收益大么&#xff1f;还是说重点是一个好的llm&#xff1f; A&#xff1a;结论是二者同步扩大才会起作用。我们试下来结论是llm 7b情况下&#xff0c…

利用AI知识库,优化医保系统售后信息管理流程

在医疗行业中&#xff0c;传统知识库管理虽能整合医疗行业知识&#xff0c;但搜索和管理效率有限&#xff0c;导致医护人员难以高效利用。特别是面对医保系统等复杂系统时&#xff0c;他们常需依赖人工客服或繁琐的电子产品手册解决问题。而HelpLook AI知识库利用AI技术&#x…

中国人民解放军信息支援部队成立

中国人民解放军信息支援部队成立 ----------强化信息化战争能力&#xff0c;维护国家安全 阅读须知&#xff1a; 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或…

基于 Win32 编程,使用 C语言开发一个记事本。

现在 Win32 非常少见&#xff0c;因为太原始了&#xff0c;同时也因为高级语言做应用开发速度更快。但是用 C 语言开发一个 win32 记事本对于理解应用程序运行的内部原理还是很有帮助的&#xff0c;“最基础的就是最有用的”&#xff0c;Windows 编程圣经 《Windows 程序设计》…

HCIP学习笔记

个人学习hcip笔记 供参考 笔记有些乱 之后还会修改完善并添加其他篇幅 OSPF篇 OSPF采用组播方式发送hello包&#xff0c;组播地址为224.0.0.5 相关&#xff1a; 所有节点&#xff1a;224.0.0.1&#xff1b; 所有路由器&#xff1a;224.0.0.2&#xff1b; OSPF DRO发给DR&…

tcp inflight 守恒算法背后的哲学

tcp inflight 守恒拥塞控制的正确性 很久以前我开始纠结 tcp 锯齿&#xff0c;很多年后我知道这叫 capacity-seeking&#xff0c;甚至说 tcp 属于 capacity-seeking protocol 的原因就是它早已深入人心的 aimd 行为&#xff0c;而该行为生成了 tcp 锯齿。 在消除锯齿&#xf…