初原挽风
文章22
标签17
分类0

一言

文章归档

算法基础 - 二分

算法基础 - 二分

二分的本质是解决在某一个区间中,存在一个性质可以将区间一分为二,便可以使用二分找到符合该性质的点。

整数二分

在整数二分中,分为二个模板。

当答案唯一时,二个模板,没有任何区别。

  • 右侧符合答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool check(int x) {  } // 检查 x 是否满足二分性质

// 右侧符合答案
int bsearchR(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check()) r = mid;
// 注意:当 check() 成功后,变换规则: r = mid 时,mid = l + r + 1 >> 1
else l = mid + 1;
}

return l;
}


给定一个升序数组如:[1, 3, 5, 5, 7, 9]
需要找到符合大于等于 5 的下标
那么使用该模板,找到的下标为 2
  • 左侧符合答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool check(int x) {  } // 检查 x 是否满足二分性质

// 左侧符合答案
int bsearchL(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check()) l = mid;
// 注意:当 check() 成功后,变换规则: l = mid 时,mid = l + r + 1 >> 1
else r = mid - 1;
}

return l;
}


给定一个升序数组如:[1, 3, 5, 5, 7, 9]
需要找到符合小于等于 5 的下标
那么使用该模板,找到的下标为 3

为什么第二个模板需要 l + r + 1 。

因为整数除法是向下取整,当 mid = (l + r) / 2,l = mid ,如果 l = 0 ,r = 1 时,由于向下取整, mid = 0 ,l = mid = 0 ,那么就陷入的死循环。

浮点数二分

浮点数二分,不存在整数除法的向下取整,所以不存在整数二分的情况。

1
2
3
4
5
6
7
8
9
10
11
12
bool check(double x) { ... } // 检查 x 是否满足二分性质

double bsearch(double l, double r)
{
while (r - l >= 1e-6) // 当 r - l 小于某一个很小的值后,认为 r/l 相等。
{
double mid = (l + r) / 2;
if (check()) r = mid;
else l = mid;
}
return l;
}
本文作者:初原挽风
本文链接:https://www.wanlu.fun/793ccc97.html
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可