二分查找 二分答案 套路模板
二分查找(二分答案)套路模板
二分查找 红蓝染色法【基础算法精讲 04】_哔哩哔哩_bilibili
提要
二分答案是一种高效的算法策略,适用于解决最值问题和单调性验证问题。它的核心思路是将问题转化为对答案的判定过程,通过二分法快速缩小搜索范围
笔者写的都是以左闭右开区间为主的
下面笔者会按照一道题的做题顺序来分析步骤,建议你最好先做一下或者起码要把题读了再往下读
Day69 | 灵神 | 二分查找:爱吃香蕉的珂珂-CSDN博客
题解
1 | class Solution { |
步骤
笔者认为解题难点一般都在check函数如何设计和处理
1.看单调性并找要二分什么
拿到一道题我们如何判断这道题可以使用二分查找?看单调性
即当答案增大或减小时,问题的答案呈现单调变化,有点抽象,看看在本题中代表着什么呢?
在本题中
看示例 1,piles=[3,6,7,11], h=8
如果珂珂能用 k=4 的速度吃掉所有香蕉,那么也能用更快的速度 k=5,6,⋯ 吃掉所有香蕉
如果珂珂不能用 k=3 的速度吃掉所有香蕉,那么也不能用更慢的速度 k=2,1,⋯ 吃掉所有香蕉
这个单调性就说明了我们可以使用二分查找找到答案
那我们怎么知道要看k的单调性呢?
因为这是题目让我们求的东西,二分答案,那肯定是二分这道题让求的东西
所以一般二分什么呢?二分的就是题目让求的
2.找二分区间,即确定搜索范围
即找答案所在的区间,即我们要二分的真正的区间,根据题目条件找答案的上界和下界
在本题中,
题目说piles的大小小于时间h,这使得我们很容易找到k的最大值,那就是数组的最大值,我每个小时吃这么多肯定可以吃得完,而最小值肯定不能是0,因为怎么都不可能吃完,所以从1开始
那么我们要二分的k的区间就是[1,数组最大值],在第一个例子中就是[1,11]
笔者用的左闭右开区间,那就是[1,数组最大值)
找到之后就可以写模板上去了,例如区间是左闭右开[left,right)
1 | int l=left,r=right; |
3.找判断条件,即写验证函数check()
编写 check(mid)
函数,判断当前 mid
是否满足条件,然后转变思维把mid当成一个定值,思考check函数到底要解决一个什么样的实际问题
在本题中,要解决的问题变成:(这个很关键,碰到难题的时候能不能想到这里决定能不能解题)
- 判断珂珂能否用 k 的速度,在 h 小时内吃掉所有香蕉。
我们二分的是k,是速度,那要如何判断一个k是否满足条件?那就看这个k可以在多少小时(sum)内吃完香蕉,如果这个sum小于等于h,那肯定就是符合条件的k,那么[k,数组最大值]
这个区间肯定都符合条件,然后继续往左收缩就是了,如果不符合条件的k的话,那说明吃得太慢了,那就往右收缩
1 | bool check(vector<int>& piles,int k,int h) |
能整除就直接加,不能整除就+1,算出时间
4.满足条件更新l还是r
更新l还是r就看你的check函数怎么写了
本题就看sum是大于还是小于h了,本题是sum小于等于h,找的是左边界,只要mid满足条件,那么大于mid的肯定都满足条件,所以更新r,这是顺向的思维,你要非写成sum>h返回true的话也不是不行
5.返回答案的问题
为什么要把返回答案的问题拿出来说呢?
假设一开始的区间是[left,right)
本道题更新的是r,说明如果符合条件,那么[r,right)肯定都符合条件
而最后退出循环是l==r的时候退出,所以最后返回l或者返回r都是最后答案
但是在更新的是l的时候呢?比如这题Day73 | 灵神 | 二分查找 最大合金数-CSDN博客,即找最大值,即从左往右收缩的时候
更新l时,更新的是l=mid+1,但是满足条件的是mid,而不是mid+1,很有可能mid+1就不符合条件,如果mid+1符合条件,那么l和r一定会更新到这里并且循环不会结束的
如果是在最后一次循环结束后即l=mid+1之后,使得l==r导致了循环退出,那么其实mid+1并不符合条件
所以如果满足check函数之后更新的是l=mid+1,最后需要返回l-1,而不是l
6.适用的题型以及条件要求
现在说这个估计大家就能更好的看懂的,如果放在开头感觉有点云里雾里
使用场景
最值问题:如“最大值最小化”(如最小化最大子段和)或“最小值最大化”(如最大化最小间隔),这个东西笔者学的也不求行,就不多说了
单调性问题:当答案增大或减小时,问题的可行性呈现单调变化(如更大的间隔可能导致更少的可行解),这个就是我举例的那道题的类型
条件要求
有界性:答案必须存在于一个确定的区间内(例如整数范围 [0, 1e9]),即我们的二分区间应该有明确的上界和下界
单调性:验证函数需满足单调性,即若答案 mid
可行,则所有更小(或更大)的值也一定可行(取决于问题方向),这个就是我们上面说的单调性,大家通过这个题目应该很好的理解了
笔者的关于灵神作业的题解
Day65 | 灵神 | 二分查找:红蓝染色法-CSDN博客
Day66 | 灵神 | 二分查找:咒语和药水的成功对数-CSDN博客
Day67 | 灵神 | 二分查找:统计公平数对的数目-CSDN博客
Day68 | 灵神 | 二分查找:H指数II-CSDN博客
Day69 | 灵神 | 二分查找:爱吃香蕉的珂珂-CSDN博客
Day70 | 灵神 | 二分查找:完成旅途的最少时间-CSDN博客
Day71 | 灵神 | 二分查找 最小化数组中的最大值-CSDN博客
Day72 | 灵神 | 二分查找 礼盒的最大甜蜜度-CSDN博客
Day73 | 灵神 | 二分查找 最大合金数-CSDN博客
灵神的题单
更多的题在这里,感兴趣的读者可以自行选择