二分查找——不但可具体位置,也可查左边界或右边界

首先二分查找的时间复杂度都是O(logN)级别的,这就意味着在有序数组的查找中,如果没有提前直到下标,那么二分查找的效率是高于一次for循环的遍历的,所以这也就是为什么许多题都在考察二分查找。

1.简单二分查找

那么接下来,我们先来看看二分查找的最常用的场景:查一个有序数组的某一数字是否存在(下标)
在这里插入图片描述

//target意为目标数字
public int searchNum(int target){
int l=0;
int r=nums.length-1;
while(l<=r){
	int mid=(l+r)/2;
	if(nums[mid]==target){
		return mid;
	}else if(target<nums[mid]){
		r=mid-1;
	}else{
		l=mid+1;
	}
}
return -1;//表示没有找到该数字
}

2.复杂二分查找(查找左边界)

假设有一个有序数组{1,2,2,2,3},这个时候让你查找target=2的边界,计算之后返回的结果肯定是是按下标处理过后:(1,3)
这个时候你可能会觉得,这有啥?费这么大劲?用什么二分法?沙13吧?当然,这个数组长度非常短,费不着用什么二分法,一次遍历就可以解决。那么如果数组很长尼?O(N)和O(logN)你倾向与哪个?答案就在下面:配合着图和代码你就知道了:
在这里插入图片描述

//target=2
public int findLeftBound(int target){
	int l=0;
	int r=nums.length; //这里需要注意
	while(l<r){
		int mid=(l+r)/2;
		if(nums[mid]>=target){  //这里需要注意
			r=mid;
		}else{
			l=mid+1;
		}
	}
	return l;
}

至于为什么会是这样?这其实就和作用域一样,左闭右开/左闭右闭,自己画个图就明白了

3.复杂二分查找(查找右边界)

其实和查找左边界没什么多大区别,只是在返回的时候需要注意,因为作用域是[L,R),所以在返回有右边界的时候-1再返回:

public int findRightBound(int target){
	int l=0;
	int r=nums.length;
	while(l<r){
		int mid=(l+r)/2;
		if(nums[mid]>target){
			r=mid;
		}else{
			l=mid+1;
		}
	}
	return r-1;
}

详细可以再看看leetcode34题,题解中有一个大牛写的特别好;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值