题目:二分查找
存在问题的地方:
- 边界条件while(left __ right)中是 < 还是 <=
- 循环中if(nums[middle] > target) right = _____中是middle还是middle - 1
应该在区间上讨论:
- 左闭右闭:[ left , right ]
- 左闭右开:[ left , right )
- 左开右闭:( left , right ]
- 等等情况…
[ left , right ]时
初始:
left = 0
right = numsize - 1
目标:找target,有返回下标,没有返回-1
然后进入 while(left ____ right) 小于还是小于等于的 讨论
首先看区间定义,以左闭右闭的区间来写二分法代码。那么观察写小于等于在这个区间里是不是一个合法的区间。什么是合法区间,至少要符合这个区间的定义才是。小于等于也就是说多了一个left和right相等的情况,在这个区间内合不合法,举个例子数组只有1个元素1 那么 [ left , right ] 即 [ 1 , 1] ,合法
然后进行循环的查找
while(left <= right){ //1. < 还是 <=middle = (left + right) / 2;if(nums[middle] > target)right = ______; //2. middle 还是 middle - 1...
}
这是左闭右闭的一个区间,已经判断middle所在的值大于target,说明nums[middle]一定不是我们搜索的值。所以我们接下里的区间是一定不要包含这个数值,即 [left , middle - 1]
if(nums[middle] > target)right = middle - 1;//middle 还是 middle - 1
此时如果写middle的话,[ left , middle ] 包含了这个nums[middle],而条件已经判断了nums[middle]>target了,此时把不是自己搜索区间里面的值又放到了下一个循环里边接着去搜索了,此时边界处理有问题。
if(nums[middle] > target)right = middle;//如果写middle
[ left , right )时
在这个区间里显然left和right不能相等,举例 [ 1 , 1)
开的意思就是不包含右边的这个边界,闭的意思就是包含左边的这个边界。又包含1又不包含1,不是一个合法的区间
while(left < rifht)
然后再来看下区间 [ left , right)
就是不包含right这个数值,此时nums[middle]已经大于target了,说明下一个搜索的左区间是不包含这个middle所在的数值。那么接下来的搜索区间本来就不包含right,那么right正好等于middle,在这个新的左区间里进行搜索。
if(nums[middle] > target)right = middle;
而此时如果target大于nums[middle],左闭右开的区间包含了左边界这个值,此时已经明确nums[middle] < target,middle不是我的target,那么接下来的区间不能包含这个middle,所以接下来的区间是[ middle + 1 , right),这才是一个新的我们要搜索的区间,符合我们左闭右开的一个原则。
else if(nums[middle] < target)left = middle + 1;