算法学习13——笔试老大难,二分法的各种模板

二分法

个人觉得二分法学习分两个阶段,第一个阶段是处理各种基本的二分场景,就是在数组中根据下标来搜索各种想要的数;第二阶段就是不再基于数组构建二分模型,而是各种搜索,我觉得很多题的难度不亚于动态规划。第二阶段只能靠多练习吧。

模板

二分基本型

二分的本质是,根据某一个判断(条件),在一个排序数组中检索某一个数,基本型的意思就是,这个判断有三种结果:大于、小于、等于,我们只需要返回使等于成立的情况。并且只需要和当前数进行比较,不需要和左右比较。

public int find(int[] arr, target){
	//一些空值、基本情况的判断
	checksomething();
	int left = 0;
	int right = arr.length - 1;
	//保证区间中最少只能有一个数
	while(left <= right){
		int mid = left + (mid - left)/2;
		//产生一个三个结果的比较
		int res = check(arr[mid], target);
		if(res == 0) return mid;
		else if(res < 0) left = mid + 1;
		else right = mid - 1;
	}
	return -1;
}

例题:就是在排序数组中找个数字

左区间的最大值

在某个条件下,数组划分为左右两个区间,求左区间的边界

public int find(int[] arr, target){
	//一些空值、基本情况的判断
	checksomething();
	int left = 0;
	int right = arr.length - 1;
	int res=0;
	//保证区间中最少只能有一个数
	while(left <= right){
		int mid = left + (mid - left)/2;
		//判断当前值是否处于左区间中
		boolean res = check(arr[mid], target);
		if(res) {
			left = mid + 1;
			res = mid;
		}else {
			right = mid - 1;
		}
	}
	return res;
}

例题:x的平方根
本题需要寻找x平方根的整数位,其实就是求:平方小于x的整数中,最大的那个数,也就是左区间最大值的问题。

右区间的最小值

这个情况上述情况可以等价互换

public int find(int[] arr, target){
	//一些空值、基本情况的判断
	checksomething();
	int left = 0;
	int right = arr.length - 1;
	int res=0;
	//保证区间中要有两个值
	while(left < right){
		int mid = left + (mid - left)/2;
		//判断当前值是否处于左区间中
		boolean res = check(arr[mid], target);
		if(res) {
			//①此时的区间大小限制是left < right,可能left = mid+1以后可能导致left=right,并且left还是处于左区间中就跳出了循环
			left = mid + 1;
		}else {
			right = mid;
		}
	}
	if(!check(arr[left],target)) return left;
	else return -1;
}

例题:第一个错误版本
一个排序数组,左边都是正确的版本,右边都是错误的版本,寻找第一个错误版本,也就是右区间最小值问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值