一、算法描述
二、算法实现
三、问题
1. 循环条件(为什么 是 <=)
2. 中间索引(i + j /2 有问题)
当数字比较大时,会超出int数的最大范围,就会变成负数(因为Java中的数都是有符号的,所以最高位都是符号位,0代表正,1代表负):
如何解决:(无符号右移的方式)。移动之后,又把这个数字移动到Java能表示的最大正数范围内了。
这个原理即使在JS里也同样适用:
3. 比较符号(为什么都是 <)
因为二分查找是升序排列的,所以写成 < 符号,能更好匹配(左边的小,右边的大)
四、改动版(左闭右开)
基础版 i 和 j 不仅是搜索边界,同时都参与比较,称为左闭右闭边界;
而改动版中 j 只作为范围外的边界值,不是查找范围内的数值,不参与比较,称为左闭右开边界。
五、二分查找性能
六、改进版解决左右查找不平衡问题
因为左闭右开的情况,会让在查找最右边元素比查找最左边元素,时间多一倍(因为每次都要比较左边的元素是否相等),因此设计成 i 值可能是中间值,也可能比中间值小。不在循环中找出,等范围内只剩 i 值时退出循环,循环外比较 a[i] 与target的值。
七、LeftRightMost
这个left和right都是针对于target而言:
返回的i值,若没有查找成功,即 i = - ( 插入点 + 1 )