前提条件:
1)数组为有序数组;
2)数组中无重复元素(出现重复元素,则利用二分法查找返回的下标值不唯一);
【如果是一个问题且待查找的数为整数,大概可以使用二分查找算法】
类型:
左闭右闭+左闭右开+左开右闭(较少)
易错点:
1)left与right的初始值为numsSize还是numsSize-1?
2)while循环中是(left<rigth)还是(left<=right)?
3)right或者left是等于middle还是middle-1?
算法:
1)初始化left(左下标)与righ(右下标)的值,再计算middle(中间下标)的值;
2)每次根据nums【middle】与target的值进行判断:
nums【middle】<target ——> left=middle+1;
nums【middle】>target ——> right=middle-1;
nums【middle】==target ——> return middle;
3)若target值不存在数组中,则return -1;
深度理解:
(1)左闭右闭型:eg:【1,5】,numsSize=5
1)初始化left=0,right=numsSize-1;
//因为数组的下标与数列排序相差1,数列中第一个元素的数组下标从0开始,则左下标left=0;
//左闭右闭型,右边元素可以取到,数组的下标与数列排序相差1,所以最右边的元素放入数组中下标为【numsSize-1】,则右下标right=numsSize-1;
2)while(left<=right)
//这里要left=right,假设left=right=1,【1,1】对于定义【1,5】有意义,即left<=right;3)计算middle的大小
不推荐:middle=(left+right)/2
//俩个int类型的数值相加可能会超出限制;
推荐:middle=left+(right-left)/2
4)if(nums[middle]<target),left=middle+1
//left此时需要右移,因为nums[middle]比target小,明确了nums【middle】不是我们需要的target值,所以left不需要考虑nums【middle】的值,而应该移到nums【middle】的下一位,即left=middle+1;
5)if(nums[middle]>target),right=middle-1
//rigth此时需要左移,因为nums【middle】比target大,明确了nums【middle】不是我们需要的target,所以left不需要考虑到nums【middle】,而应该移动到nums【middle】的前一位,即right=middle-1;
6)if(nums【middle】=target),return middle;
7)如果查询完发现target没有在数组中,则return -1;
(2)左闭右开型:eg:【1,5),numsSize=5
1)初始化left=0,right=numsSize
//因为数组的下标与数列排序相差1,数列中第一个元素的数组下标从0开始,则左下标left=0;
//左闭右开型,最右边元素取不到,假设现有一个数组{1,2,3,4,5},当right=5时,可以取到下标为0,1,2,3,4的元素,所以右下标right=numsSize对于定义【1,5)有意义,即right=numsSize;
2)while(left<right)
//这里不能取等号,假设left=right=1,【1,1)左边取1右边不取1,显然left与right不能相等,所以left<right;
3)计算middle的大小
4)if(nums[middle]<target),left=middle+1
//左闭,左边元素取得到(同上);
5)if(nums[middle]>target),right=middle
//右开,右边元素取不到,nums[middle]明确比target值大,不是我们所需的target,但因为是右开型,当right=middle时,所考虑的数组范围中没有包含nums【middle】,从此时考虑的范围为【left,middle)即【left,middle-1】;
6)if(nums【middle】=target),return middle;
7)如果查询完发现target没有在数组中,则return -1;
以上仅为个人学习笔记,若有错误,请指正