二分查找算法
二分查找算法
二分查找算法是一个非常常用的算法,也能解决很多问题,只要在一个区间内存在一个元素,使得这个数的左边满足某种性质,但是右边不满足这个性质,就可以用二分查找算法找出这个元素。
整数的二分查找
整数的二分查找会产生很多的边界问题
bool check(int);
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
return l;
}
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
return l;
}
第二个模板与第一个模板的差距在于边界条件,简单来说,当mid是由向下取整
得到的时候,在区间变换时就一定不能出现l=mid
的表述,同样的,当mid是由向上取整
得到的时候,在区间变换的时候就一定不能出现r=mid
的表述
浮点数的二分查找
浮点数的二分查找不涉及边界问题,较为简单。
示例
c++:
#include <iostream>
using namespace std;
int main()
{
double n;
scanf("%lf", &n);
double l = -10000, r = 10000;
while (r - l >= 1e-8)
{
double mid = (l + r) / 2;
if (mid * mid * mid >= n)
r = mid;
else
l = mid;
}
printf("%f", l);
return 0;
}
python:
n = float(input())
l, r = -10000, 10000.0
while r-l > 1e-12:
mid = (l+r)/2
if mid**3 >= n:
r = mid
else:
l = mid
print("%.6f" % (l))
#include <iostream>
using namespace std;
const int N = 1000010;
int n, m;
int q[N];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%d", &q[i]);
while (m--)
{
int x;
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (x <= q[mid])
r = mid;
else
l = mid + 1;
}
if (q[l] != x)
cout << "-1 -1" << endl;
else
{
cout << l << " ";
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (x >= q[mid])
l = mid;
else
r = mid - 1;
}
cout << l << endl;
}
}
return 0;
}
其他题目