二分算法复习

一、原理及适用条件

1、当数组有“二段性”时就能使用(注意不仅仅是递增或递减的有序数组)

2、用找到的 mid 值来比较二段之间的不同,进而得出边界的移动情况。

二、一般二分法

1、适用场景

此时要找的目标值只有一个,存在或不存在,就对应找到或没找到。

2、模板

while(left <= right)

{

        int mid  = (right - left) / 2 + left;

        if(....)

                left = mid + 1;

        else if(...)

                right = mid - 1;

        //找到了

        else

                return ...

}

//没找到

return ....;

3、例题

. - 力扣(LeetCode)

三、左右边界二分

1、总结模板

此题不同于一般二分,他的target是可能出现多次,找到一个不是找到答案,不难看出是要找数组中target的左右边界。

(1)左边界

此时我们要得到左边界就要让left与right相遇,我们知道在这张图上left在左区间永远不合法,所以left每次移动必定是越过mid,争取能到右区间与right相遇,右区间是永远合法,所以right每次移动万万不能越过mid,不然无法维持右区间特性。

左区间模板

while(left < right)

{

        int mid = (right - left) / 2 + left;

        if(...)

                left = mid + 1;

        else

                right = mid;

}

//最后left与right相遇,但是不一定就是最终答案,要判断特殊情况

....

(2)右边界

与左区间类似。

右区间模板

while(left < right)

{

        int mid = (right - left + 1) / 2 + left;

        if(...)

                left = mid;

        else

                right = mid - 1;

}

//最后left与right相遇,但是不一定就是最终答案,要判断特殊情况

....

2、细节问题

(1)为什么判断条件是 left < right

在一般二分中,判断条件是 left <= right,是因为答案就一个,如果答案存在就要在循环里面直接返回,因为left一次移动到mid左边,right移到mid右边,左右指针不可控,不像左右边界模板,至少有一个指针永远不会超出合法范围。所以要用一般二分,就一定要在循环里面返回正确结果,或在循环外面返回找不到。

从上面表述来看其实所有的一般二分都能转化成左右边界二分。

那为什么边界二分left和right不能相等?

在有结果时,即left == right,进入循环,mid == left,mid == right,此时必有一个判断条件让left = mid 或 right = mid,导致死循环。

(2)mid如何计算

左边界 mid = (right - left) / 2 + left; 要选中点靠左的,因为当左右区间只有两个元素时,选中点靠右的当要执行 right = mid时,right不会左移导致死循环。

右边界 mid = (right - left + 1) / 2 + left;

四、例题

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

. - 力扣(LeetCode)

五、经验

1、一上来就要找二段性!!!!!!!!

2、结果一定要在等于的区间。

3、left与right相遇不一定是结果,要考虑特殊情况!!!!!!

4、思考时不要想模板,要找到具体每道题的分类讨论正确移动指针方式,不要被模板限制思维。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值