小白都能玩的算法day5-二分查找

小白讲故事,每日都精彩。

啪啦啪啦,小白批试卷。长得帅满分,长得俏满分,会说话满分。

前提:摆在小白面前是排好序的试卷

目标:调皮的小白想从中挑出漂亮小姐姐嬴政的试卷

聪明的你会通过什么方式快速帮小白找到?

二分查找

没错今日小白给大家带来有趣的二分法。(小白就喜欢二八分偏偏头)

从试卷思考

小白也是去过嵩山,练过武功,常常看《赌神》。就希望有朝一日,练成千王之手,在江湖有一席地位。(此处省略一万字。。。)

小白一出手,就知有没有。摸出一个张李四。(人在江湖漂,哪有不失手的)

别灰心!我们知道嬴政大美女在李四的后边。再来次,从后边摸一张。哦豁,摸出个姚明。(长得高得人就爱出风头)

小白原谅你这次。现在还剩两张试卷,那可是百分百命中。哈哈~~~

费劲千辛万苦,总算揭开了大美女嬴政的面纱。

查找过程

从规模上寻找最差和最好情况

小白以为自己已经是高高高手,自信能一次命中。(最好情况)

然而,现实是残酷的。找无可找,才得到目标。(最坏情况)

那这个过程是怎样的?

假设我们当前规模是1000,那么需要查多少次?

其实我们可以用1000除以2,直到剩下1。那么需要多少次?

我们知道2的9次方等于512,2的10次方等于1024,那么我们求得x就应该介于9次方到10次方之间。

规模设想

那么我们就推导T(n)公式了,如图:

规模关系猜想

(提示:是值下限,相当于Math.floor,就这么理解吧)

如果你不相信,小白就跟你理论,哪个好看哪个请客。通过一个数N是否是2的K次幂的角度论证。论证如下:

论证一

论证二

从例子到抽象

从之前我们的将栗子中抽象成代码:

function bSearch(A, x)
A: 是数组
x:是要查找的数
结果: 返回x的位置,存在
       返回-1,不存在
复制代码

看看我们是查找22的过程。

查找

(l左边界,r右边界,g猜想)

第一次:我们通过左边界和右边界取中间值(1),Math.floor((l+r)/2),g得到坐标5,也就是33

对比:22在33的左边,所以右边界r = 5-1 = 4

第二次: 重复(1)的操作,g得到坐标2,也就是19

对比:22在19的右边,所以右边界了= 2+1 =3

第三次: 重复(1)的操作,g得到坐标3,也就是22,得到结果。

循环不变式

最后小白献上代码一份:

function bSearch(n, x){
    let l = 0, // 查询范围左边界
        r = n.length, // 查询范围右边界
        guess; // 猜想位置
    while(l <= r){
        guess = Math.floor((l+r)/2);
        // 循环不变式
        // guess等于l,r中间位置

        if(n[guess] === x) return guess;
        if(n[guess] > x){ // x在n[guess]的左边
            r = guess - 1
        }else{ // 否则就在右边
            l = guess + 1
            // 循环不变式:新的查找范围
        }
    }
    return -1
}
复制代码

今日一题

写一个函数,将字符串除了最后的四位,其他都变成#

maskify("4556364607935616") == "############5616"
maskify(     "64607935616") ==      "#######5616"
maskify(               "1") ==                "1"
maskify(                "") ==                 ""

// "What was the name of your first pet?"
maskify("Skippy")                                   == "##ippy"
maskify("Nananananananananananananananana Batman!") == "####################################man!"
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值