二分搜索

75 阅读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 - 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,右开不变,理解记忆即可