Problem5800--学习系列 —— 二分 —— 二分查找

5800: 学习系列 —— 二分 —— 二分查找

[Creator : ]
Time Limit : 1.000 sec  Memory Limit : 256 MiB

Description

二分查找也是一种在有序数组中查找数据的算法。它只能查找已经排好序的数据。
二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边。因此,比较一次就可以把查找范围缩小一半。重复执行该操作就可以找到目标数据,或得出目标数据不存在的结论。

【查找过程】

下面我们在下边有序的数组,试试查找数字 $6$ 吧。该数组对应的下标索引为 $1,2,\cdots,9$。

首先找到数组中间的数字,此处为 $5$。因为 $(1+9)/2=5$,使用下标进行加法。

将 $5$ 和要查找的数字 $6$ 进行比较。

在剩下的数组中找到中间的数字,此处为 $7$。因为 $(6+9)/2=7$。

比较 $7$ 和 $6$。

在剩下的数组中找到中间的数字,此处为 $6$。6=6,成功找到目标数字。

数据量为 $n$ 的数组,将其长度减半 $log_2n$ 次后,其中便只剩一个数据了。也就是说,在二分查找中重复执行“将目标数据和数组中间的数据进行比较后将查找范围减半”的操作 $log_2n$ 次后,就能找到目标数据(若没找到则可以得出数据不存在的结论),因此它的时间复杂度为 $O(logn)$。
特别注意:该方法只能查找唯一的数据。

Input

模板代码

const int N=2e6+10;
LL a[N];

//在 [l,r] 中找到 x 的下标 
LL bsearch(LL l, LL r, LL x) {
	while (l<r) {
		LL m=(l+r)/2;
		if (a[m]==x) {
			return m;
		} else if (a[m]>x) {
			r=m-1;
		} else {
			l=m+1;
		}
	}
	return l;
}

Output

特别注意:
二分查找总是能找到一个需要的索引位置。我们需要对数据的合法性进行判断。

Source/Category