当前位置: 首页 > news >正文

二分查找法详解(6种变形)

前言
在之前的博客中,我给大家介绍了最基础的二分查找法(没学的话点我点我!)

今天我将带大家学习二分法的六种变形如何使用,小伙伴们,快来开始今天的学习吧!
在这里插入图片描述

文章目录

  • 1,查找第一个(从左到右)= 目标值的,若不存在返回 -1
  • 2,查找第一个 >= 目标值的
  • 3,查找第一个 > 目标值的
  • 4,查找最后一个 = 目标值的 ,若不存在返回- 1
  • 5,查找最后一个 <= 目标值的
  • 6,查找最后一个 < 目标值的
  • 总结

1,查找第一个(从左到右)= 目标值的,若不存在返回 -1

与原版二分法其实差不多,当一个数组中有重复的目标值时,使用该方法可以找到从左到右第一个等于目标值的下标。
因为我们要找的是第一个等于目标值的下标,那我们不仅仅在arr[mid] > key时去左边找,在arr[mid]>= key我们也要去找,因为我们需要要最左边等于目标值的下标。
注意事项
最后我们要判断left是否越界(left 有可能等于数组元素的个数),而且最后arr[left]是否等于要找的key。
代码:

int efcz(int* arr, int key,int left,int right)
{int len = right+1;//数组长度(元素个数)int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] >= key){right = mid - 1;}if (arr[mid] < key){left = mid + 1;}}if (left < len&&arr[left] != key)//判断一下是否找到元素return -1;elsereturn left;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,5,6 };//创建数组int key = 5;//目标值为5int left = 0;//设置左右起点int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key,left,right));//进入二分查找函数return 0;
}

2,查找第一个 >= 目标值的

这次我们需要查找第一个大于等于目标值的下标,这次我们不需要判断left越界,如果越界就说明没有找到,说明整个数组都比目标值要小。
代码:

//思路和第一种一样,我就不加注释了,如果不懂可以私信问我
int efcz(int* arr, int key, int left, int right)
{int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] >= key){right = mid - 1;}if (arr[mid] < key){left = mid + 1;}}return left;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,6,8 };int key = 7;int left = 0;int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key, left, right));return 0;
}

3,查找第一个 > 目标值的

这次我们需要查找第一个大于目标值的下标,这次我们同样不需要判断left越界,如果越界就说明没有找到,说明整个数组都比目标值要小。
另外我们需要改变一下函数内部的判断条件,当arr[mid] <= key时,left = mid + 1
因为我们不是要找相等的,是要找大于目标值的。
代码:

//思路和第一种一样,我就不加注释了,如果不懂可以私信问我
int efcz(int* arr, int key, int left, int right)
{int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] > key){right = mid - 1;}if (arr[mid] <= key){left = mid + 1;}}return left;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,6,8 };int key = 5;int left = 0;int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key, left, right));return 0;
}

4,查找最后一个 = 目标值的 ,若不存在返回- 1

因为我们要找的是第一个等于目标值的下标,那我们不仅仅在arr[mid] < key时去右边找,在arr[mid]>= key我们也要去找,因为我们需要要最右边边等于目标值的下标。
注意事项
最后我们要判断right是否越界(right 有可能等于-1),而且最后arr[right]是否等于要找的key。
代码:

//思路和第一种一样,我就不加注释了,如果不懂可以私信问我
int efcz(int* arr, int key, int left, int right)
{int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] > key){right = mid - 1;}if (arr[mid] <= key){left = mid + 1;}}if (right >= 0 && arr[right] == key)//判断是否找到return right;elsereturn -1;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,6,8 };int key = 5;int left = 0;int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key, left, right));return 0;
}

5,查找最后一个 <= 目标值的

这次我们需要查找第一个小于等于目标值的下标,这次我们不需要判断right越界,如果越界就说明没有找到,说明整个数组都比目标值要大。
代码:

//思路和第一种一样,我就不加注释了,如果不懂可以私信问我
int efcz(int* arr, int key, int left, int right)
{int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] > key){right = mid - 1;}if (arr[mid] <= key){left = mid + 1;}}return right;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,6,8 };int key = 4;int left = 0;int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key, left, right));return 0;
}

6,查找最后一个 < 目标值的

这次我们需要查找第一个小于目标值的下标,这次我们同样不需要判断right越界,如果越界就说明没有找到,说明整个数组都比目标值要大。
另外我们也需要改变一下函数内部的判断条件,当arr[mid] >= key时,right = mid - 1,因为我们不是要找相等的,是要找小于目标值的。
代码:

//思路和第一种一样,我就不加注释了,如果不懂可以私信问我
int efcz(int* arr, int key, int left, int right)
{int mid = (left + right) / 2;while (left <= right){mid = (left + right) / 2;if (arr[mid] >= key){right = mid - 1;}if (arr[mid] < key){left = mid + 1;}}return right;
}
int main()
{int arr[10] = { 1,2,3,5,5,5,5,5,6,8 };int key = 5;int left = 0;int right = sizeof(arr) / sizeof(arr[0]);printf("%d", efcz(arr, key, left, right));return 0;
}

总结

我认为可以分两组记忆这六种变形,前三组一类,后三组一类,前三组都是返回left,后三组都是返回right,同时我们会发现,第一种和第四种,第二种和第五种,第三种和第六种都十分的相似,所以自己练练就能掌握,而且不容易忘记,本期的分享就到这里,如果觉得博主讲的不错的话,千万不要忘记给博主一个关注,点赞,收藏哦~,小伙伴们,我们下期再见!

相关文章:

二分查找法详解(6种变形)

前言 在之前的博客中&#xff0c;我给大家介绍了最基础的二分查找法&#xff08;没学的话点我点我&#xff01;&#xff09; 今天我将带大家学习二分法的六种变形如何使用&#xff0c;小伙伴们&#xff0c;快来开始今天的学习吧&#xff01; 文章目录 1&#xff0c;查找第一个…...

uniapp uview 页面多个select组件回显处理,默认选中

<view class"add-item column space-around" click"selectClick(1)"><text class"w-s-color-3 f-28">商品分类</text><view class"w-100 space-between"><!-- 第一个参数为你的单选数组&#xff0c;第二个…...

linux中playbook的控制语句

本章主要介绍 playbook中的控制语句。 使用 when 判断语句 block-rescue判断 循环语句 一个play中可以包含多个task&#xff0c;如果不想所有的task全部执行&#xff0c;可以设置只有满足某个 条件才执行这个task&#xff0c;不满足条件则不执行此task。本章主要讲解when 和 …...

MongoDB介绍

一、MongoDB介绍 1.1 mongoDB介绍 MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB …...

再看参数校验

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 写一个接口&#xff0c…...

计算机存储术语: 扇区,磁盘块,页

扇区(sector) 硬盘的读写以扇区为基本单位。磁盘上的每个磁道被等分为若干个弧段&#xff0c;这些弧段称之为扇区。硬盘的物理读写以扇区为基本单位。通常情况下每个扇区的大小是 512 字节。linux 下可以使用 fdisk -l 了解扇区大小&#xff1a; $ sudo /sbin/fdisk -l Disk …...

解决IDEA编译/启动报错:Abnormal build process termination

报错信息 报错信息如下&#xff1a; Abnormal build process termination: "D:\Software\Java\jdk\bin\java" -Xmx3048m -Djava.awt.headlesstrue -Djava.endorsed.dirs\"\" -Djdt.compiler.useSingleThreadtrue -Dpreload.project.path………………很纳…...

Jetpack DataStore

文章目录 Jetpack DataStore概述DataStore 对比 SP添加依赖库Preferences DataStore路径创建 Preferences DataStore获取数据保存数据修改数据删除数据清除全部数据 Proto DataStore配置AndroidStudio安装插件配置proto文件创建序列化器 创建 Proto DataStore获取数据保存数据修…...

在Portainer创建Nginx容器并部署Web静态站点实现公网访问

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…...

泛微e-cology XmlRpcServlet文件读取漏洞复现

漏洞介绍 泛微新一代移动办公平台e-cology不仅组织提供了一体化的协同工作平台,将组织事务逐渐实现全程电子化,改变传统纸质文件、实体签章的方式。泛微OA E-Cology 平台XmRpcServlet接口处存在任意文件读取漏洞&#xff0c;攻击者可通过该漏洞读取系统重要文件 (如数据库配置…...

当下流行的直播技术demo演示

nginx-http-flv-module&#xff08;更新不是很频繁&#xff09; SRS: https://ossrs.net/lts/zh-cn/&#xff08;独立官网&#xff0c;目前最新稳定版version5&#xff09; 基于SRS搭建直播demo演示&#xff1a; 一、搭建流媒体服务器 参见官网&#xff1a;https://ossrs.ne…...

Zabbix自动发现并注册已安装agent的主机

先在被监控主机上安装好zabbix-agent 然后登录zabbix网页 点击发现动作后会出现第三步 然后编辑操作&#xff0c;发现后加入到主机组群 然后编辑发现规则 然后就可以在主机列表中看到被发现的主机。...

Jtti:linux搭建开源ldap服务器的方法

搭建开源LDAP服务器是一种用于集中管理用户身份认证和授权信息的方法。在Linux系统上&#xff0c;OpenLDAP是一个流行的开源LDAP实现&#xff0c;可以用于搭建LDAP服务器。以下是搭建OpenLDAP服务器的基本步骤&#xff1a; 步骤一&#xff1a;安装OpenLDAP 安装OpenLDAP软件包&…...

Gazebo GUI模型编辑器

模型编辑器 现在我们将构建我们的简单机器人。我们将制作一个轮式车辆&#xff0c;并添加一个传感器&#xff0c;使我们能够让机器人跟随一个斑点&#xff08;人&#xff09;。 模型编辑器允许我们直接在图形用户界面 &#xff08;GUI&#xff09; 中构建简单的模型。对于更复…...

pycharm运行正常,但命令行执行提示module不存在的多种解决方式

问题描述 在执行某个测试模块时出现提示&#xff0c;显示自定义模块data不存在&#xff0c;但是在PyCharm下运行正常。错误信息如下&#xff1a; Traceback (most recent call last):File "/run/channelnterface-autocase/testcases/test_chanel_detail.py", line 2…...

GBASE南大通用GBase 8a ODBC的安装文件

GBASE南大通用GBase 8a ODBC 体系结构是基于五个组件&#xff0c;在下图中所示&#xff1a; GBase 8a ODBC 体系结构图  应用 应用是通过调用 ODBC API 实现对 GBase 数据访问的程序。应用使用标准的 ODBC 调用与驱动程序管理器通信。应用并不关心数据存储在哪里&#xff…...

重新配置torch1.8 cuda11.1 torchtext0.9.0虚拟Pytorch开发环境

这里写目录标题 起因发现选择安装cuda 11.1核对下自己的显卡是否支持下载该版本的CUDACUDA下载地址CUDA安装过程 在anaconda中创建一个虚拟环境1.以下是环境的配置过程2.查看虚拟环境列表3.激活虚拟环境 安装torch和torchtext包的过程1.输入下面这句代码&#xff0c;就可以直接…...

【动画图解】一次理清九大排序算法!面试官问到再也不慌!

排序算法 交换排序 冒泡排序快速排序 插入排序 直接插入排序希尔排序 选择排序 简单选择排序堆排序 归并排序基数排序桶排序 一、冒泡排序 冒泡排序是一种简单的交换排序算法&#xff0c;以升序排序为例&#xff0c;其核心思想是&#xff1a; 从第一个元素开始&#xff0c…...

组播地址段及其作用

作用 组播(Multicast)传输:在发送者和每一接收者之间实现点对多点网络连接。如果一台发送者同时给多个的接收者传输相同的数据&#xff0c;也只需复制一份的相同数据包。它提高了数据传送效率。减少了骨干网络出现拥塞的可能性。 地址段 组播协议的地址在 IP 协议中属于 D 类…...

Vue+ElementUI前端添加展开收起搜索框按钮

1、搜索框添加判断 v-if"advanced" <el-form-item label"创建日期" v-if"advanced"><el-date-pickerv-model"daterangeLedat"size"small"style"width: 240px"value-format"yyyy-MM-dd"type&q…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...