基于力扣题目704,对二分法的一个学习记录
对于二分法:我们应该很熟悉,不就是折半查找嘛!但是经常让我们迷糊的是那个while循环里的条件到底是< 还是 <= 呢?还有中点出是middle+1还是middle-1,这写决定这一循环条件的是查找区间的划分:
主要分为一下几类:
左闭右闭
左闭右开
左开右闭(很少见)
对于第一种情况的代码:
至于为什么是等于,就需要我们去判断[left,right]是否是合法区间,例如[1,1],但left = right能找到一个元素,所以我们可以等于右边界。第一个if语句里,为什么 rigth = middle - 1,因为区间是左闭右闭,二if条件里明确nums[middle] > target,所以middle已经不再查找范围内,需要排除掉。加一同理。
class Solution {
public int search(int[] nums, int target) {
//左闭右闭写法
int left = 0, rigth = nums.length - 1;
while(left <= rigth) {
int middle = (left + rigth) / 2;
if(nums[middle] > target){
rigth = middle - 1;
}else if(nums[middle] < target){
left = middle + 1;
}else {
return middle;
}
}
return -1;
}
}
而第二种情况:左闭右开代码如下,因为右边的区间是开的,所以left ==right无意义。//右边是开的,查找是已经不包括在内,不用减一,//nums[middle] < target 明确指出target大于中间值,又是闭区间需要排除该值
int left = 0, rigth = nums.length;
while(left < rigth) {
int middle = (left + rigth) / 2;
if(nums[middle] > target){
//右边是开的,查找是已经不包括在内,不用减一
rigth = middle;
}else if(nums[middle] < target){
//nums[middle] < target 明确指出target大于中间值,又是闭区间需要排除该值
left = middle + 1;
}else {
return middle;
}
}
return -1;