数据结构之二分法

二分法时间复杂度为O(logn),主要思想就是不断缩小区间范围,最后找到要找的那个数。

  1. 第一步:首先找到中间位置,即左边界、右边界的和除以2
  2. 第二步:判断要的数位于那个区间,如果在左边界和中间位置之间,那么右边界就要移到中间位置;如果在右边界和中间位置之间,那么左边界就要移到中间位置
  3. 第三步:再次确定中间位置,重复1,2步,直到找到要找的那个数
vector<int> v(5);
int right=4,left=0;
while(left<right)
{
	int mid=(left+right)>>1;
	if(v[mid]<x)
		left=mid+1;
	else
		right=mid;
	...
}
return v[left]

但是二分法最后还有个关键点,就是边界问题,如果大了可能死循环,如果小了可能漏掉要找的那个数,下面我们严谨的看看这个边界逻辑;
就比如上面的代码,left=mid+1,为什么right=mid,不是right=mid-1其实我们仔细想也能想到,如果right=mid-1就可能漏掉我们要找的数,比如1 2 3 4 5 ,我们要找到3,第一次mid可以找到3,大于等于3即x,所以应该向左边靠,如果right=mid-1,right就到了2的位置,第二次mid将会找到1, 1<3然后向右靠,left最后没有找到3,而是到了2,退出循环;但是right=mid,第一次mid也是找到3,然后right到了3的位置,第二次mid找到2,2<3然后left到了3的位置,最后一次找到3,退出循环,left最后就是等于3。
当然如果执意想用right=mid-1也可以,就需要在循环中加入mid==x即我们要找的那个数就返回,x循环提交也需要改一下,保证不漏掉数,不如正好mid=left=right这种情况,最后其实不用返回v[left]了,因为循环内已经有返回了,如下:

vector<int> v(5);
int right=4,left=0;
while(left<=right)
{
	int mid=(left+right)>>1;
	if(v[mid]==x) return v[mid];
	if(...)
		left=mid+1;
	else
		right=mid-1;
	...
}
return -1;

当然如果数组中肯定有要找的数,那么可直接改条件即可:

vector<int> v(5);
int right=4,left=0;
while(left<=right)
{
	int mid=(left+right)>>1;
	if(...)
		left=mid+1;
	else
		right=mid-1;
	...
}
return v[left]

其他的办法也可以,只要不漏掉数就可以

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值