二分法
对于边界规则,分为右开和右闭,即是否选取右边界(默认左闭,即选取左边界)
右闭
const nums = [1, 2, 3, 4, 5, 6, 7]
const target = 6
let left = 0
let right = nums.length - 1
while(left <= right) {
let middle = Math.floor((left+right)/2) // 向下取整 防止越界
if(nums[middle] < target){
right = middle - 1
} elif(nums[middle] > targrt) {
left = middle + 1
} else {
return middle
}
}
return -1
右开
const nums = [1, 2, 3, 4, 5, 6, 7]
const target = 6
let left = 0
let right = nums.length - 1
while(left < right) {
let middle = Math.floor((left+right)/2) // 向下取整 防止越界
if(nums[middle] < target){
right = middle
} elif(nums[middle] > targrt) {
left = middle + 1
} else {
return middle
}
}
return -1
理解
不难发现,循环对应的就是右边界是否等于middle的问题
展开看遍历,即可理解
对于右闭
const nums = [1, 2, 3, 4, 5, 6, 7]
const target = 2
第一次运行,middle=3,left=0,right=6 移动时,如果right=3,相当于进行了不必要的判断,因为3已经被检测过了,所以-1
对于右开
const nums = [1, 2, 3, 4, 5, 6, 7]
const target = 2
第一次运行,middle=3,left=0,right=6 移动时,如果right=3,实际上不包含3,而是只有从0到2,所以直接赋值即可
left因为为闭区间,所以移动时+1
规律:右闭-1,右开不变,理解记忆即可