浅谈二分算法

浅谈二分算法

二分

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

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

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

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

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

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

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

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

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

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

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

双指针

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

设所求元素为 p p p,序列为 a a a

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

否则 l ← m i d + 1 l\leftarrow mid+1 lmid+1,将区间控制为 [ m i d + 1 , r ] [mid+1,r] [mid+1,r]

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

二分查找的边界条件

枚举以下情况
  • 闭区间

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

示意图:

  • 开区间

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

示意图:

  • 左开右闭

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

示意图:

  • 左闭右开

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

示意图:

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

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

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值