算法-查找-二分法
二分法
写二分法时首先要看要搜索的区间,一般来讲区间有左闭右开,左闭右闭两种,这个区间决定着while时left是小于等于还是小于。
左闭右开
[ left, right ),也就是这样的搜索区间,先挂代码
1 | class Solution { |
首先搜索区间里要是一个有序的数组,然后才能用二分,查找流程
- 比较目标值是否在这个搜索区间,比最小的小比最大的大就不再,直接return
- 规定区间,left,right,由你想要的搜索区间决定right的值,right=nums.length时就代表这个区间是右开的,因为right的值访问不到
- 然后while循环,循环条件这里,根据你的区间决定,这里如果是<=就是不和法的,由第二步知,right访问不到,也就是left<=right这里left不能等于right 如:[1,1),这里右边的1是取不到的,所以只能是小于
- 设置中间值middle,这里left直接加right可能会由溢出的风险,可以采用下面这种写法
1 | int middle=left+(right-left)/2; |
- 然后将中间值与目标值进行比较,如果大于就更新,right的值,这里right为什么要等于middle呢? middle不是已经比较过了吗? 原因就是我们的区间里right的值取不到,所以right可以直接更新为middle
- 根据第五步,如果小于,left=middle+1,这里为什么不是middle,应该不用解释了,因为这里left可以取到,middle已经比较过了,就不用放到这次的搜索区间里了
- 最后一种情况就是等于,可以直接return middle值,也就是目标值的下标
- 如果循环结束,还没找到,可以直接ruturn 象征没找到的数字
左闭右闭
[ left,right ],这样的搜索区间,以下是代码
1 | class Solution { |
与左闭右开大部分步骤一致,以下是不同
1 | int left=0,right=nums.length-1; |
这里right的值为length-1,正好是数组最后一个的下标,可以访问到
1 | while(left<=right) |
left可以等于right,因为区间是左闭右闭,是合法的,
1 | if(nums[middle]>target){ |
这里middle进行了减一,这里与上面第六步的原因一致
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Zsh的树洞!
