二分算法刷题总结

二分搜索算法

基本的二分查找框架

  • 简单查找,找到目标值在数组中的位置下标,如果没有则返回-1
int binarySearch(vector<int>& nums, int target){
	int left = 0, r = nums.size() - 1;
	while(left <= right){
		int mid = left + (right - left) / 2;
		if(target == nums[mid] ){
			return mid;
		}else if(target > nums[mid]){
			left  = mid + 1;
		} else{
			right = mid - 1;
		}
	}
	return -1;
}

注意点:

  • while(left <= right)中是"<“还是”<="号取决于right的取值,因为上述模板中的right取值为nums.size()-1,即搜索区间为闭区间[left, right]。对应的left = mid + 1right = mid - 1中应该有+1-1的操作。
  • 反之,如果取right = nums.size(),则表示为左闭右开的区间[left, right),所以while循环中应该是while(left < right>,不能取相等。当改变搜索空间时对应的应该为:left = mid + 1right = mid。因为在上一次的搜索中,开区间right的值并未取到,而左边闭区间的left是已经被遍历计算过,所以left = mid + 1.

寻找左侧边界的二分搜索

  • 上述方法存在缺陷
    比如说给你有序数组nums = [1,2,2,2,3]target为 2,此算法返回的索引是 2,没错。但是如果我想得到target的左侧边界,即索引 1,或者我想得到target的右侧边界,即索引 3,这样的话此算法是无法处理的。
//找到数组中=target值得最左侧边界得下标值
int binarySearch(vector<int>& nums, int target){
	int left = 0, r = nums.size() - 1;
	while(left <= right){
		int mid = left + (right - left) / 2;
		if(target == nums[mid] ){
			//区别,当找到一个值与target相等时,不能确定是否是最左侧边界,因此需要缩小搜索范围为[left, mid - 1]
			right = mid - 1;
		}else if(target < nums[mid]){
			right = mid - 1;
		} else{
			left  = mid + 1;
		}
	}
	//注意:需要判断边界,由于 while 的退出条件是left == right + 1,所以当target比nums中所有元素都大时,会使得索引越界:
	if(left >= nums.size() || nums[left] != target)
		return -1;
	return left; // 返回相等得最左侧边界值得下标
}

寻找右侧边界的二分搜索

int binarySearch(vector<int>& nums, int targer){
	int left = 0, right = nums.size() - 1;
	while(left <= right){
		int mid = left + (right - left) / 2;
		if(target >= nums[mid])
			left = mid + 1;
		else if(target < nums[mid])
			right = mid - 1;
	}
	//判断边界条件,当target比nums中所有元素都小时,会使得right减小为负数,索引越界
	if(right < 0 || nums[right] != target)
		return -1;
	return right;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值