方法一:左闭右闭
左闭合右闭合是指target是再一个左闭合右闭合的区间里面,也就是[left, right] ,值可能是left,也可能是right。
1. 设置查找区间:left = 0;right = arr.length-1(最后一个元素的index);
2. 在left<=right这个区间里面进行查找循环,超出此区间,则查找失败,返回-1;否则转步骤3
3. 取中间位mid = (low + high) / 2;比较 target 与 arr[mid],有以下三种情况:
3.1 若 target < arr[mid],我们已经判断出出来mid大于target了,说明mid一定是不在我们的左区间里面的,我们接下来的空间是不包括mid的,因为我们要寻找的区间一定是完全每比较过的,所以接下来的搜索区间是right = mid - 1;查找在左半区间进行,转步骤2;
3.2 若 target > arr[mid],同理,更新右区间里面的做边界值,因为mid已经比较过了,则left = mid + 1;查找在右半区间进行,转步骤2;
3.3 若 target = arr[mid],则查找成功,返回 mid 值;
重点1:while(left<=right) 比如只有一个元素[1],这个时候left=0,right=0,middle=0,我们还是要进行查找的。
重点2:right = middle -1/ left = middle + 1
var search = function (nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
let middle = Math.floor((left + right) / 2);
if (nums[middle] < target) {
left = middle + 1;
} else if (nums[middle] > target) {
right = middle - 1;
} else {
return middle;
}
}
return -1;
};
方法二:左闭右开
target是在一个左闭右开的区间里面,也据说[left,right),target是不可能在right的这个位置的。
1. 设置查找区间:left = 0;right = arr.length-1(最后一个元素的index);
2. 在left< right这个区间里面进行查找循环,超出此区间,则查找失败,返回-1;否则转步骤3
3. 取中间位mid = (low + high) / 2;比较 target 与 arr[mid],有以下三种情况:
3.1 若 target < arr[mid],我们已经判断出出来mid大于target了,要更新左边区间了。左闭右开说明不包含右边的这个,我们mid已经大于target了,说明下一个搜索的区间是不包含mid的,所以接下来的搜索区间是right = mid 就可以了;查找在左半区间进行,转步骤2;
3.2 若 target > arr[mid],同理,更新右区间里面的左边界值,因为mid已经比较过了,不是我们的target,我们是左闭右开,搜索范围是包括左边界的,则left = mid + 1;查找在右半区间进行,转步骤2;
3.3 若 target = arr[mid],则查找成功,返回 mid 值;
重点1:while(left <right)这个时候左闭右开,结果肯定没在right里面,所以left<right就行.
注意开始的索引,right是index+1,因为right是开,不再target范围里
重点2:right = middle ; left = middle + 1
var search = function (nums, target) {
let left = 0;
// right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间
let right = nums.length;
while (left < right) {
let middle = Math.floor((left + right) / 2);
if (nums[middle] < target) {
left = middle + 1;
} else if (nums[middle] > target) {
right = middle;
} else {
return middle;
}
}
return -1;
};