待做:leetcode有几道题目涉及到二分查找的变形!
二分查找是很常用的一个小技巧,思想很简单,就是在排序完的数组中不断的折中查找使得效率从O(n)降到O(lgn)。
但是在编程的时候总是会遇到一些小问题:死循环,边界取不到等等。
假设数组含有n个元素,编号0~n-1;
边界问题:
int i = 0;
int j = n - 1;
int v = (i + j) / 2;
因为是折中判断,所以v=(i+j)/2,但是这个取v的方式使得v的
取值范围是[i, j),也就是闭头开尾,也就是
j 的值其实是取不到的,如果你还是按照j=n-1的情况,如果target刚好是最后一个数,那么永远都取不到。
死循环:
死循环的原因跟v的取值范围有关,因为v=(i+j)/2在编译器看来是舍弃小数部分。
while( i <= j)
{
v = (i + j)/2;
if(a[v] == target) {cout<<v<<endl;break;}
else if(a[v] > target) j = v;
else i = v;
}
int i = 0;
int j = n - 1;
int v = (i + j) / 2;
while( i <= j)
{
v = (i + j)/2;
if(a[v] == target) {cout<<v<<endl;break;}
else if(a[v] > target) j = v - 1;
else i = v + 1;
}
- //要把握下面几个要点:
//right=n-1 => while(left <= right) => right=middle-1;
//right=n => while(left < right) => right=middle;
//middle的计算不能写在while循环外,否则无法得到更新。
- //以上的规则在于:要能取到边界值,所以1中left <= right,2中right = middle;