二分模板总结

最近做题做二分老是卡,于是总结一下:

本人二分做题不多,只遇到过三种情况,如有错误请大佬指正:
1、递增序(即若(0,x)位置满足条件,(x + 1, n)均不满足),找最后一个满足条件的位置,如找满足某条件的最大长度。
2、递减序(即若(x + 1, n)位置满足条件,(0, x)均不满足)找第一个满足条件的位置,如找满足某条件的最小值。
3、局部满足,找任意一个递增和递减的交界点。

下面假设bool check(int n)当位置满足条件时返回true,否则返回false.

1、递增,找最后一个位置:(这种打法不需要额外确认边界条件,用ans即可判断)
目前找到的最朴实的代码,虽然每次搜索要比单边界多走一次,但是易于掌握,已储备为个人模板:这个是学数据结构时,最开始学的二分代码,结果后来把这种方法忘了,还是不能忘本。。
用ans记录最终结果即可。

		ans = -1; //-1表示没找到
		while(l <= r) {
			int mid = l + (r - l) / 2; //防止溢出
			if(check(mid)) { 
				ans = mid;
				l = mid + 1;	
			}			
			else {
				r = mid - 1;
			}
		}	
		return ans;

2、递减,找第一个位置
代码1:朴实版:(这种打法不需要额外确认边界条件,用ans即可判断)

		ans = -1;//-1表示没找到
		while(l <= r) {
			int mid = l + (r - l) / 2;//防止溢出
			if(check(mid)) {  
				ans = mid;
				r = mid - 1;	
			}			
			else {
				l = mid + 1;
			}
		}	
		return ans;

代码2:单边界移动**(这种打法需要额外确认边界条件,需要最后再check一下)**

		while(l < r) {
			int mid = l + (r - l) / 2;//防止溢出
			if(check(mid)) {  //if(a[mid] > mid)
				l = mid + 1;	
			}			
			else {
				r = mid;
			}
		}	
		int ans = -1;//-1表示没找到
		if(cheack(l))ans = l;
		return ans;

3、既有递增,又有递减,判断峰值(下面的代码假设左边递增,右边递减):

        while (l < r) {
            int mid = (l + r) / 2; //防止溢出
            if (a[mid] > a[mid + 1]) //如果右边递减,峰值只能在左边
                r = mid;
            else
                l = mid + 1;
        }
        return l;


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值