[AcWing]二分算法
代码已经在 GITHUB 开源,👉点击直达👈。
〇、算法步骤
注意,这里我并没有以闫总的二分算法模板进行讲解(我认为不好,要考虑很多边界问题)。这里讲解的算法原理来自 B 站的视频:二分查找为什么总是写错?。
在我曾经的文章:数组:二分查找 里介绍的二分查找算法有局限性。这里要介绍的二分算法核心模型是“红蓝区间(左右区间)”,而不是某个等于目标值的元素值。正因为如此,该二分算法才具有更大的灵活性,才能处理更复杂的问题。相关示意图和算法步骤如下:
- 建模:划分“红蓝区间”,确定 isBlue 判断条件。
- 确定要找的目标元素索引是 left 还是 right。
- 根据算法伪代码实现算法。
- 后处理(这里有些重要的问题处理)。
算法伪代码:
1 | left = -1, right = N |
一、算法模板
这里只给出其中一个模板,便于理解上述算法原理的文字内容。
1 | /** |
二、其他问题
这里着重讲解一下“后处理”中的关于“索引越界问题”。我认为这是这个算法唯一的小缺点,就是这个后处理需要自己多做一点判断。
首先看两个可能的判断条件:
arr[right] != target
或arr[left] != target
,通过判断返回索引对应的元素值是否与目标值相等来判断。left == -1 || right == arr.size()
,通过 left 与 right 的初始值进行判断。
然后来看几个测试样例(以寻找第一个 target 元素为例):
- 下面的测试用例通过算法后,
left = 0
且right = 1
,这意味着arr[right]
会越界!可以证明判断条件arr[right] != target
行不通(类似的在返回 left 的情况下可以推得arr[left] != target
也行不通)。"判断条件 1 的驳例" 1
arr = [-1] target = 5
- 下面的测试用例通过算法后,
left = -1
且right = 0
,但是返回值为 -1(应该返回right
)!可以证明判断条件left == -1 || right == arr.size()
行不通。"判断条件 2 的驳例" 1
arr = [5] target = 5
- 下面的测试用例通过算法后,
left = 0
且right = 1
,但是返回值为right
(应该返回 -1)!也可以证明判断条件left == -1 || right == arr.size()
行不通。"判断条件 2 的驳例" 1
arr = [1, 6] target = 5
所以,相对合适的判断方式为:right == arr.size() || arr[right] != target
或 left == -1 || arr[left] != target
。具体使用哪个,要看你的任务目标是什么,自己多推导分析可能的情况。
三、算法练习题
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SeaEpoch!
评论