二分算法基本思想就是分治。
(一)基本模板
public int binarySearch(int[] nums, int target){
int left = 0;
int right = nums.length-1;
while(left <= right){
int mid = left + ((right-left)>>1);//left+right容易溢出且移位运算比除法性能更好,故将(left+right)/2换成left +((right-left))>>1。
if(nums[mid] > target){
right = mid - 1;//目标值比中间值小,收缩右边界。
}else if(nums[mid] < target){
left = mid + 1;//目标值比中间值大,收缩左边界。
}else{
return mid; //查询到目标值并返回数组下标。
}
}
return -1;//没有查询到目标值返回-1。
}
(二)特殊情况(当数组中包含重复元素)
比如某些题目想要查询到目标值的左边界。
public int binarySearch(int[] nums, int target){
int left = 0;
int right = nums.length-1;
while(left < right){ // 不能再使用=,否则可能会导致死循环
int mid = left + ((right-left)>>1);
if(nums[mid] < target){
left = mid + 1;//收缩左边界。
}else{
right = mid; //收缩右边界。
}
}
return nums[left] == target ? left : -1;//判断最后结果是否为目标值。
}
查询右边界同理(注意:mid值的计算方式有变化)
public int binarySearch(int[] nums, int target){
int left = 0;
int right = nums.length-1;
while(left < right){ // 不能再使用=,否则可能会导致死循环。
int mid = left + ((right-left)>>1) + 1; //需要+1使得mid值偏右才能保证不陷入死循环。
if(nums[mid] > target){
right = mid - 1;//收缩右边界。
}else{
left = mid; //收缩左边界。
}
}
return nums[left] == target ? left : -1;//判断最后结果是否为目标值。
}