几个二分查找的变形

本文探讨了二分查找在处理无重复元素的升序数组以及存在重复元素时的策略。针对如何缩小问题规模和确定循环终止条件,作者详细分析了传统二分查找在查找特定key时的实现,并指出选择'low<high'作为循环条件的重要性,以避免死循环和误判。同时,文章提到了在有重复元素的数组中查找目标值最左边下标的二分查找问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分查找其实是很难的问题,主要是边界问题难以解决,下面就我自己的理解说一说,我们应该如何进行思考。

二分法主要面向两类问题,

一类是无重复元素的按升序排序的数组

另一类是面向有重复元素的数组。

而每一类都必须面临两个难点,对应如下

 

1:如何将问题的规模减小,因为二分就是分治的应用,我们必须要保证问题在逐步减小,不会出现死循环的情况。

2:while循环终止的条件,是选用low<high 还是选择low<=high(其实有这两种选择就够了,不需要有其他的写法,其余的写法其实是冗余的,可以简化)

好,下面来结合这两个难点,我们想一下如何解决如下几个问题

1:传统的二分法,求一个按升序排列的数组中是否存在某一个key

      这个问题肯定是没有重复元素的问题,先上一段代码

int binary(int Key,vector<int> nums){
	int low=0,high=nums.size()-1,mid;
	while(low<=high){
		mid=low+((high-low)>>2);
		if(nums[mid]==Key){
			return mid;
		}
		else if(nums[mid]<Key){
			low=mid+1;
		}
		else if(nums[mid]>Key){
			high=mid-1;
		}
	}
	return -1;
}

对于问题一:我们可以知道,上面对应的是三段式,当它等于的时候,就直接return这个下标,然后没找到的话,就需要进行丢弃一半的元素,例如Key>nums[mid],那么就会丢弃掉原来的low到mid之间的所有元素,总的丢掉的是mid-low+1个元素,这是大于1的,而另外一种情况,Key<nums[mid],要丢弃掉原来的mid到high之间的所有元素,也是要丢掉high-mid+1个元素,也是大于1的,这样就解决了我们的第一个问题,不会死循环,即问题的每一步都在逐渐减小。那么我们就思考,while中循环的条件,到底是选择low<=high,还是选择low<high,我们假定这样想,如果选择了第二种,那么我们最后一次循环的时候必然是low=high

那么很自然上一个的mid也等于low=high,那么这个时候,我们想,那么上一步的high不就没有判断吗?因为我们判断的时候就是[low,high],左闭右闭,最后一步,mid=low,此时high决对是没有判断的,下一步就会退出,那么就会误判。好了这个问题就到此结束

2:有重复元素的数组,求Key的最左边的那个值的下标,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值