浅谈二分算法

news/2024/11/17 6:49:44/文章来源:https://www.cnblogs.com/Atserckcn/p/18381990

浅谈二分算法

二分

首先知道一下二分是什么。

二分,是一种快速处理大型数据的方法。基本逻辑是折半查找。

设有一个共有 \(n\) 个数字的数组,要从中查询某个元素,就可以用二分查找。

注:这里的数组默认其成员数值具有单调性。这个点十分重要。

还记得小时候(我现在才新初一)跟同学玩过一个游戏(数字炸弹),当时玩得可欢了,一直以为是一个概率小游戏(其实确实有概率的成分),每局能玩上十几分钟。

但是现在学完信息学后,特别是学完二分后,对它有了一种快速解决的方法。

首先我们知道,设出题者所想的这个数字为 \(x\),则 \(x\in[1,100]\),这是我们玩的规则,不过大差不差。

那么很显然,因为 \(1\sim 100\) 具有单调上升的性质,而我们又只需要查找一个数,暴力的求解方法是从 \(1\) 尝试到 \(100\),最坏情况下需要枚举 \(100\) 次,十分漫长。

而我们可以想到,每次说出一个数 \(y\),只要不是 \(y=x\),就可以排除 \(100-y+1\)\(y\)​​ 个数(这取决于你猜的这个数是大了还是小了)。

那么我们就可以利用这个特性,假设共有 \(n\) 个数字,每次都排除 \(n\div2\) 个数字,这样最多经过 \(\log_2^n\) 次后就可以结束游戏。

其实小学课本里就有类似的例子,是数学书里一个单元叫做 “ 找次品 ” 的数学问题(不知道的自己查),但那里是用 \(\log _3^n\) 的时间,这里不再赘述。

双指针

双指针,顾名思义,就是运用两个变量 \(l,r\)​ 表示所求区间的左右端点,可以更加轻松地控制对答案有贡献的区间。

设所求元素为 \(p\),序列为 \(a\)

比如每次取个中点 \(mid=\frac{(l+r)}{2}\),若 \(p<a_{mid}\),则 \(r\leftarrow mid\),左端点 \(l\) 不变。将区间控制为 \([l,mid]\)

否则 \(l\leftarrow mid+1\),将区间控制为 \([mid+1,r]\)

但这里问题就来了,区间为空的判定条件是 \(l=r\) 还是 \(l>r\) 呢?

二分查找的边界条件

枚举以下情况

  • 闭区间

若你用的是闭区间,即 \([l,r]\),则判断条件即为 \(l=r\),因为若 \(l=r\),则 \([l,r]\) 其实就是 \([l,l]\)\([r,r]\) ,就是一个数,答案也显然即为 \(a_l\)​。

示意图:

  • 开区间

开区间,是 \((l,r)\)不包括 \(l,r\) 。所以有效区间为 \([l+1,r-1]\)。判断条件即为 \(l+1=r-1\)​。

示意图:

  • 左开右闭

左开右闭,即 \((l,r]\) 有效区间为 \([l+1,r]\),边界条件即为 \(l+1=r\)​,还是就剩下一个数为止。

示意图:

  • 左闭右开

左闭右开\([l,r)\),有效区间为 \([l,r-1]\),边界条件为 \(l=r-1\)​。

示意图:

所以可以总结一下,不管你的 \(l,r\) 都表示什么意思,重点就是四个字,有效区间

大概大家也注意到了,我在解释除了闭区间其他情况的时候,有效区间的左右端点都是用闭区间来表示,为什么呢?当然是因为我个人喜欢用闭区间啦。

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

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

相关文章

推荐

DIN假设 \(V_i^{shop},V_i^{good},V_i^{cate}\) 分别表示历史第 \(i\) 次点击的 shop_id,good_id,cate_id, \(V_a^{shop},V_a^{good},V_a^{cate}\) 分别表示候选商品的 shop_id,good_id,cate_id,则两个不同版本用户兴趣表达 \(V_u\) 计算方式如下 \[\begin{align} g\left…

优化器

优化器 目录优化器SGDAdagradAdadeltaRMSpropAdamAdamW SGD 随机梯度下降 问题:训练轨迹会呈现锯齿状,这无疑会大大延长训练时间。同时,由于存在摆动现象,学习率只能设置的较小,才不会因为步伐太大而偏离最小值。 Momentum:将一段时间内的梯度向量进行了加权平均,分别计…

读软件开发安全之道:概念、设计与实施10安全设计审查

安全设计审查1. 安全设计审查 1.1. Security Design Review,SDR 1.2. 将安全性融入软件设计的最佳方法之一是戴上“安全帽”进行单独的设计审查 1.3. 安全审查员是熟悉软件运行的系统和环境,以及知道如何使用它的人,但他们不参与设计工作,这能够给予他们距离感以保持客观性…

【Java】FastJson 利用JSONPath.eval快速获取目标json的属性值

一、需求场景: JSON串格式化之后,JSON树的属性深度太长了 二、代码实现: 语法等效MySQL的JSON读取方式 方法调用的返回类型为Object,强转至String进行处理/* 读取报告时间 */ Object reportDateEval = JSONPath.eval(jsonObject, "$.categories[0].children[0].data.…

10.网络安全技术

12-1 数据备份策略和盘阵列备备份方式12-2 加密技术12-3 入侵检测系统IDS12-4 入侵防护系统IPS脚本属于应用12-5 网络版防病毒软件的安装及配置12-6 防火墙PIX配置过程下面nameif常考内网100外网0下面管道第二常考www是默认的80端口C,监视模式TCPorUDPfixup nat global

30 分钟内了解 IEC 61850

30 分钟内了解 IEC 61850 索引术语——IEC 61850 配置、语义分层对象数据模型、客户端 - 服务器、发布 - 订阅。平时学习标准或调试IEC61850设备,需要IEC61850模拟器,推荐一款:客户端下载地址:IEC61850客户端模拟器 服务端下载地址:IEC61850服务端模拟器谣传 IEC 61850 过…

6.2K star!推荐一款开源混沌工程测试平台:Chaos Mesh

1、Chaos Mesh 介绍 Chaos Mesh是一个开源的混沌工程平台,旨在帮助用户在生产环境中测试、验证和优化其应用程序的可靠性和稳定性。通过引入故障注入和混沌工程原则,Chaos Mesh可以模拟各种故障场景,如网络延迟、节点故障、磁盘故障等,以帮助用户发现和解决系统中的潜在问题…

看图学 - Swift 并发

Swift 内置支持以结构化方式编写异步和并行代码。看着那些层层嵌套的闭包,你是不是很想把它们全都干掉? 本文首发于 Ficow Shens Blog,原文地址: 看图学 - Swift 并发。想第一时间获取对于自己有帮助的新内容? 欢迎关注 Ficow 的公众号: 看图学 - Swift 并发如需获取 PD…

《黑神话,悟空》研发公司的薪资水平

大家好,我是晓凡。 最近全网最火爆的要属《黑神话:悟空》了,即便是我这个平时不沾游戏、不追直播的人,也看直播看得津津有味。 一、销量与热度背后 首先,让我们来看看那些令人瞩目的数字。《黑神话:悟空》自发布以来,销量已经超过450万份,总销售额达到了惊人的15亿元人…

NetScaler Release 14.1 Build 29.63 (nCore, VPX, SDX, CPX, BLX) - 混合多云应用交付控制器

NetScaler Release 14.1 Build 29.63 (nCore, VPX, SDX, CPX, BLX) - 混合多云应用交付控制器NetScaler Release 14.1 Build 29.63 (nCore, VPX, SDX, CPX, BLX) - 混合多云应用交付控制器 NetScaler - 混合多云应用交付控制器 请访问原文链接:https://sysin.org/blog/netscal…

dotnet WinUI 3 修复非打包应用运行提示 Microsoft.ui.xaml.dll 找不到

本文记录一个 WinUI 3 的坑点,有时候开发者只是想拉下来代码跑一下,自己本机没有预先安装好 Windows App Runtime 导致缺失环境,进而在运行的时候提示 Unable to load DLL 找不到 Microsoft.ui.xaml.dll 启动失败详细的错误信息如下 System.DllNotFoundException:“Unable t…

读 dotnet 源代码 为何 Thread.Sleep 半毫秒和一毫秒等待时间差距如此之大

本文记录我读 dotnet 的源代码了解到为什么调用 Thread.Sleep 的时候,传入的是不足一毫秒,如半毫秒时或 0.99 毫秒,与传入是一毫秒时,两者的等待时间差距非常大大概如下的代码,分别进行两次传入给 Thread.Sleep 不同等待时间的循环测试。其中一次传入的是 0.99 毫秒,一次…