二分的本质是定义并找到某种性质的边界,边界的一侧满足该性质,另一侧不满足该性质。
- 对一个区间按某种性质进行二分时,利用该性质的判断条件,每一轮都能将区间范围减半,范围减半后的区间进入下一轮二分。显然,每次进行二分的区间都包含要求的答案,这意味着若区间长度变为 1 时,区间里的那个数就是答案。
- 使用二分法一定能找出边界,但找出的边界可能不满足算法题对解的定义,所以二分算法题可能没有解。
定义某种性质的边界的示例:
找出升序数组中某个元素的起始位置和终止位置:
- 起始位置:最左边的大于等于该元素的数的下标;
- 终止位置:最右边的小于等于该元素的数的下标。
1 2 3 4
元素索引 0 1 2 3 4 5 数组元素 1 2 2 3 3 4 目标元素 3 索引区间 [3,4]
整数二分
整数二分的要点在于中点的选取,有两个模板:
l = mid
,r
不变,即二分后的区间是[mid, r]
或[l, mid-1]
,此时取mid = (l+r+1)/2
;- 求
mid
时有个加 1,若没有加 1,当r == l+1
时,mid=(l+l+1)/2
下取整的结果就是l
,新区间[mid, r]
依然是[l, r]
,和二分之前的区间完全相同,造成死循环。
- 求
r = mid
,l
不变,即二分后的区间是[l, mid]
或[mid+1, r]
,此时取mid = (l+r)/2
。
- 模板记法:二分后新区间的
-1
和mid
的+1
同时出现。
找出升序数组中某个元素的起始位置和终止位置:
|
|
浮点数二分
浮点数的三次方根:
|
|
References