leetcode-二分查找算法总结

news2024/9/22 15:38:54

最朴素二分查找算法:

最朴素二分查找算法:

最基础的一道题:基于有序数组的二分查找--. - 力扣(LeetCode)

基本流程:

1:实际上二分查找不一定非得要有序,能否使用二分查找的关键是是否具有二段性.

2:基于有序数组的二分查找算法也没有规定必须要均分.对于有序数组不论你取哪个点都具有二段性.只不过在中间取分割点的方式效率最高,时间复杂度为Olog(n);

时间复杂度:

从有序数组的二分查找我们可以抽象出来朴素二分查找的模板:

省略的内容是确定二段性的过程,需要自己根据题目找出确定二段性的方式

不朴素二分查找

不朴素二分查找其实就是二分查找的循环里左右指针的行为为:1 :left = mid + 1,right = mid或者2: left = mid right = mid  - 1这两种时的二分查找。这里给出模板解决上述俩种情况的边界处理问题。

以. - 力扣(LeetCode)"在排序数组中查找元素的第一个和最后一个位置"为例:

直接通过朴素二分查找确定的元素无法确定他在目标区间的位置,也就不知道是不是第一个和最后一个位置的元素.所以朴素二分查找无法解决这道题.

这道题我们可以通过题目分解为俩部分:1:找第一个位置 2:找最后一个位置

找目标元素出现的第一个位置即目标元素左端点:

第一段(数组左端到left)为不包含目标元素的区间,第二段(right到数组右端)为包含目标元素的区间。mid指针不断移动对俩个区间进行扩张直到找出左端点。具体来说:

        *如果mid小于target,left = mid + 1;
        *如果mid大于等于target,right = mid;   

        *循环结束条件:while(left < right)                       

这里的二段性怎么分析出来的? 注意这里找的是左端点.左端点就能得出来一个特性,左端点的左边一定是不包含目标元素.由此我们将数组分为:包含目标元素和不包含目标元素俩段.俩段的临界点即我们要去拿到的左端点

        细节:    

                    1:循环结束的判断:一定要为left < right,如果是left <= right 那么在判定到最终结果时,判定条件为if(nums[mid]>=nums[right]) right=mid,此时就会陷入到死循环当中。
                    2:对于mid的确定(元素个数为偶数时mid的位置为偏左一个数还是偏右一个数):mid一定要得到偏左那个数,即left + (right - left)/2.          原因:如果到了left和right指针相邻的情况时,mid落在了右边那个数,那么right = mid,mid再次计算位置不变这个过程就形成了一个死循环。(剩下俩个数左边那个一定小于或者等于嘛,右边那个数一定大于或者等于嘛,结合left和right的移动规则就知道要到偏左那个位置)

模板:

找目标元素出现的最后一个位置即目标元素右端点:

对于右端点来说,它的二段性进行了改变:
第一段:包含target的区间;(0,left]
第二段:不包含target的区间。(right , nums.length - 1)
所以left和right的行为相比较与左端点的求法就需要进行改变:
*mid <= right left = mid
*mid > target right = mid - 1.

这里left和right的移动规则进行了改变,则mid的确定方法就得进行改变。mid需要确定到偏右的位置,否则就会进入死循环,所以要使用:left + (right - left + 1)/2

其它注意事项和原理与求左端点基本相同.

实例:

模板:

在遇到二分查找的问题时,我们首先根据题意确定左右指针的行为,行为确定后如果是 不朴素二分查找我们就直接通过上述模板确定循环结束条件,mid的表达式等。

例题:

不朴素二分查找:

                非递减数组求目标元素的左右端点 :. - 力扣(LeetCode)

                 旋转数组最小值. - 力扣(LeetCode)将数组抽象成图形就会发现其二段性(俩个升序段,且第二个升序的最大值比第一段小):以第一个元素或者最后一元素为flag,mid值比flag大说明mid在第一段,否则在第二段。所以左右指针的行为就应该是:if(nums[mid] < flag)right = mid; else left = mid + 1然后套用模板解决问题

                x的平方根:. - 力扣(LeetCode)举个例子:8的平方根在2和3之间,但是这里的规则是取2即小数直接去掉。所以做指针的行为就应该是if(nums[left]的平方 <= taget)left = mid else right = mid - 1.然后套用模板就能解决问题。

                搜索插入位置:. - 力扣(LeetCode)按照题意不存在目标值target时返回第一个大于目标值的下标。所以左右指针的行为就是:if(nums[left] < target)left = mid + 1  else right = mid

然后套用模板即可

                山脉数组峰顶索引:. - 力扣(LeetCode)

利用山脉的上升和下降通过mid和mid + 1值比较判断二段性。上升阶段left可以压缩到mid + 1下降阶段righ可以压缩到 mid所以left和right行为:

if(arr[mid] >= arr[mid + 1]) right = mid;else left = mid + 1;然后套用模板。

                点名:. - 力扣(LeetCode)二段性:缺席之前下标等于学号,缺席之后下标不等于学号。下标和对应的学号进行比较得到二段性。当 下标 != 学号 时right压缩到mid,当下标 == 学号时left 压缩到mid + 1.由此得到left和right指针行为:if(mid != records[mid]) right = mid;else left = mid + 1;然后套用模板即可

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

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

相关文章

jetbrains 、IntelliJ IDEA、PyCharm 等工具英语音译读音

本心、输入输出、结果 文章目录 jetbrains 、IntelliJ IDEA、PyCharm 等工具英语音译读音前言jetbrains 、IntelliJ IDEA、PyCharm 等工具英语音译读音jetbrains 、IntelliJ IDEA、PyCharm 等工具英语音译读音 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_…

谷粒商城实战笔记-55-商品服务-API-三级分类-修改-拖拽数据收集

文章目录 一&#xff0c;拖拽后结点的parentCid的更新二&#xff0c;拖拽后结点的父节点下所有结点的sort排序属性的变化更新排序的逻辑代码分析 三&#xff0c;拖拽后结点及其子节点catLevel的变化判断是否需要更新 catLevel获取拖动后的新节点 更新 catLevel完整代码 这一节的…

服务器数据恢复—V7000存储硬盘故障脱机的数据恢复案例

服务器存储数据恢复环境&#xff1a; 某品牌P740小型机AIXSybaseV7000磁盘阵列柜&#xff0c;磁盘阵列柜中有12块SAS机械硬盘&#xff08;其中包括一块热备盘&#xff09;。 服务器存储故障&#xff1a; 磁盘阵列柜中有一块磁盘出现故障&#xff0c;运维人员用新硬盘替换掉故障…

【安当产品应用案例100集】003-基于SSL VPN架构,通过ASP Radius认证机制强化远程办公

SSL VPN远程安全接入技术&#xff0c;想必大家都已有所耳闻。简而言之&#xff0c;这项技术允许你在家中或其他远程位置&#xff0c;通过安全、可靠的途径访问公司内部的网络资源&#xff0c;从而实现无缝、无差别的远程办公体验。它作为企业远程访问的优选方案&#xff0c;其简…

SpringBoot热部署重启关闭(DevTools)

一、DevTools依赖 1、DevTools简介 在Spring Boot项目中&#xff0c;spring-boot-devtools模块提供了多种开发时的便利功能&#xff0c;其中最显著的是restart和livereload特性&#xff0c;它们分别用于应用代码的热重启和前端资源的即时重载。 devtools依赖&#xff1a; &l…

UCOSIII 时间片轮调度接口OS_SchedRoundRobin详解

时间片轮调度&#xff08;Round-Robin Scheduling&#xff09;是一种常见的任务调度算法&#xff0c;它将CPU时间片均匀地分配给每个任务&#xff0c;确保每个任务在一定时间内能够获得CPU资源。这种调度方式适用于需要公平分配CPU时间的系统&#xff0c;特别是在有多个相同优先…

叶再豪老师-【番外篇-主升三域】课程

文章目录 1.番外篇1.1番外篇:【道篇】1.1.1 课程目录1.1.2 大道至简1.1.3 欲速则不达&#xff0c;见小利则大事不成1.1.4 强弱转换规律1.1.5 创战法以和道&#xff0c;成为简单快乐的投资者1.1.6 融合道&#xff0c;服务众生&#xff0c;离苦得乐 1.2 番外篇:【势篇】1.2.1 顺势…

Adobe国际认证详解-从零开始学做视频剪辑

从零开始学做视频剪辑&#xff0c;是许多初学者面临的挑战。在这个数字媒体时代&#xff0c;视频剪辑已经成为一种重要的技能&#xff0c;无论是个人爱好还是职业发展&#xff0c;掌握视频剪辑技能都是非常有价值的。 视频剪辑&#xff0c;简称“剪辑”&#xff0c;是视频制作过…

maven archetype

1.简介 maven脚手架是为了创建一个项目模板&#xff0c;以后新建项目都能够复用该模板 maven中模板引擎使用的是velocity,在文件中可以使用它的语法获取变量等操作 2.实现 单模块脚手架实现 pom.xml <?xml version"1.0" encoding"UTF-8"?> &…

无人机之起飞过程操作

一、开启无人机电源 1、开启电源时&#xff0c;再次确认无人机各个部件工作正常&#xff0c;传感器未被遮挡&#xff1b; 2、将无人机放置在平坦的地面上&#xff0c;并开启电源。 二、进行预起飞检查 1、通过无人机的控制系统执行预起飞检查&#xff0c;包括检测罗盘、GPS…

【Unity2D 2022:UI】无法拖拽TextMeshPro组件

在预制体Card上挂载了四个Text Mesh Pro组件&#xff0c;分别命名为Name、HP、ATK、Description。 将预制体Card挂载脚本CardDisplay用来在预制体上显示属性&#xff0c;并创建TextMeshPro对象来接收TextMeshPro组件。 using TMPro; using UnityEngine; using UnityEngine.UI;…

Air780EP模块 LuatOS开发-MQTT接入阿里云应用指南

简介 本文简单讲述了利用LuatOS-Air进行二次开发&#xff0c;采用一型一密、一机一密两种方式认证方式连接阿里云。整体结构如图 关联文档和使用工具&#xff1a;LuatOS库阿里云平台 准备工作 Air780EP_全IO开发板一套&#xff0c;包括天线SIM卡&#xff0c;USB线 PC电脑&…

Harmony Next -- 通用标题栏:高度自定义,可设置沉浸式状态,正常状态下为:左侧返回、居中标题,左中右均可自定义视图。

hm_common_title_bar OpenHarmony三方库中心仓&#xff1a;https://ohpm.openharmony.cn/#/cn/detail/common_title_bar 介绍 一款通用标题栏&#xff0c;支持高度自定义&#xff0c;可设置沉浸式状态&#xff0c;正常状态下为&#xff1a;左侧返回、居中标题&#xff0c;左…

uniapp的h5,读取本地txt带标签的文件

效果图 使用的回显的标签是u-parse&#xff0c;下面的网址讲了这个标签的相关 https://www.cnblogs.com/huihuihero/p/12978903.html 导入此插件 https://ext.dcloud.net.cn/plugin?id364 使用 uni.request({// 本地文件url: "/static/互联网医院医师端用户协议.txt…

初学C++30道选择题带答案(1)

题目 (31) 下面程序的输出是 A) 0 0 3 B) 0 1 2 C) 1 0 3 D) 1 1 2 #include <iostream> using namespace std; main() { int a-1,b4,k;k(a<0)&&(!(b--<0)); cout<<k<<a<<b;} (32)以下…

Nginx 怎样处理请求的并发控制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 Nginx 怎样处理请求的并发控制&#xff1f;一、并发控制的重要性二、Nginx 中的并发连接限制三、Nginx 的请求队列四、Nginx 的限流机制五、Nginx 的负载均衡策略…

TypeScript中Interface接口的深度探索与实践

定义接口 在TypeScript中&#xff0c;interface是一个强有力的概念&#xff0c;它用于定义类型签名&#xff0c;特别是对象的结构。接口可以用来描述对象应该有哪些属性、方法&#xff0c;以及这些成员的类型。它们是实现类型系统中“鸭子类型”&#xff08;duck typing&#…

小试牛刀-区块链WalletConnect协议数据解密

目录 1.编写目的 2.工作原理 3.分析过程 3.1 websokcet连接 3.2 连接后的消息 3.3 获取sym_key 3.4 解密数据 Welcome to Code Blocks blog 本篇文章主要介绍了 [WalletConnect协议数据解密] ❤博主广交技术好友&#xff0c;喜欢文章的可以关注一下❤ 1.编写目的 最近在…

<HMI><汇川>在汇川IT7000系列的HMI(触摸屏)中,如何为你的画面设置全局样式?

前言 汇川的HMI软件是使用了Qt来编写的,因此在汇川的HMI程序编写过程,是支持使用qt的样式来自定义部件样式的,即qss格式。 概述 汇川的软件本身提供三个系统的style样式,我们可以直接使用,但是,如果系统提供的样式不符合你的需求,那么你可以对其进行修改,或者自己新建…

计算机网络-配置路由器ACL(访问控制列表)

配置访问控制列表ACL 拓扑结构 拓扑结构如下&#xff1a; 要配置一个ACL&#xff0c;禁止PC0访问PC3&#xff0c;禁止PC4访问PC0&#xff0c;其它正常。 配置Router0 配置接口IP地址&#xff1a; interface fastethernet 0/0 ip address 192.168.1.1 255.255.255.0 no shu…