二分算法

二分查找

要求

数据是有序且单调的

模板

从左到右

	while (l < r)
    {
        int mid = l + r >> 1;	//(l+r)/2
        if (check(mid))  r = mid;    // check()判断mid是否满足性质	//arr[mid] >= x
        else l = mid + 1;
    }

从右到左

	while (l < r)
    {
        int mid = l + r + 1 >> 1;	//(l+r+1)/2
        if (check(mid))  l = mid;	//arr[mid] <= x
        else r = mid - 1;
    }

若存在所找数不存在的情况只需要在循环结束后进行判断:

if(arr[mid] != num)	//...

浮点二分

	while(r-l>1e-5) //需要一个精度保证,一般比要求的多两位即可(经验)
	{
		double mid = (l+r)/2;
		if(check(mid)) l=mid; //或r=mid;
		else r=mid; //或l=mid;
	}

二分答案

要求

  1. 答案属于一个区间,且区间是单调的
  2. 直接搜索不好搜,但是容易判断一个答案可行不可行

另一个典型特征:求…最大值的最小,求…最小值的最大

模板

求…最大值的最小:及二分答案的时候,判断条件满足后,尽量让答案往靠,(即:让r=mid)对应模板从左到右

求…最小值的最大:及二分答案的时候,判断条件满足后,尽量让答案往靠,(即:让l=mid)对应模板从右到左

解题方向

最短距离最大化问题:保证任意区间距离要比最短距离mid大或相等(这样,mid才是最短距离)即:区间的距离>=mid

最长距离最小化问题:保证任意区间距离要比最大距离mid小或相等(这样,mid才是最大距离)即:区间的距离<=mid

posted @ 2023-08-27 23:32  -37-  阅读(8)  评论(0编辑  收藏  举报