二分思想的本质

本质思想
通过二分法查找有序数列中某个数字的下标,只是二分法的一种应用,二分法的本质是找到性质的边界。

查找有序数列的数字x,本质是x将数组分成了两个性质,x左边的数满足性质1:小于等于x;x右边的数满足性质2:大于等于x。

在该情境下,无论是左边性质还是右边性质,边界都是一样的(假设序列中只有一个x)。这里假设通过求左边性质的边界,达到求x下标的目的。

int binary_search(int a[], l, r, x) {
	while (l < r) {
		int mid = (l + r + 1) >> 1;
		// 性质: <=x,检查mid是否满足性质
		if (a[mid] <= x) l = mid;
		else r = mid - 1;
	}
	return a[l];
}

这里mid = (l + r + 1) >> 1,是为了防止出现死循环。如果不加1,当l = r - 1时,mid=l,而接下来的判断可能会使得l = mid,就会发生mid一直等于l的情况,发生死循环。

处理边界
对于二分法,思想不难,但是边界问题很难处理,yxc提供了一种模版非常好用,上面的代码也是根据模版所写。

以下模版适用于整数二分:

// 求右边性质边界
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 求左边性质边界
int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}
posted @ 2021-11-19 18:02  moon_orange  阅读(87)  评论(0编辑  收藏  举报