二分查找

大体分为两种写法
1.左闭右闭 [l,r]
2.左闭右开 [l,r)

左闭,右闭 [l, r]
  1. 输入数组不可重复
  2. 输入数组可重复,输出最左侧符合条件的值
  3. 输入数组可重复,输出最右侧符合条件的值
// 输入数组不可重复
function searchNotRepate(nums, target) {
  let l = 0
  let r = nums.length - 1
  while (l <= r) {
    const mid = Math.floor(l + (r - l) / 2)
    if (nums[mid] > target) {
      r = mid - 1
    } else if (nums[mid] < target) {
      l = mid + 1
    } else {
      return l
    }
  }
  console.log({ l, r })
  return -1
}

// 输入数组可重复,输出最左侧符合条件的值
function searchHasRepateLeft(nums, target) {
  let l = 0
  let r = nums.length - 1
  while (l <= r) {
    const mid = Math.floor(l + (r - l) / 2)
    if (nums[mid] < target) {
      l = mid + 1
    } else {
      r = mid - 1
    }
  }
  console.log({ l, r })
  if (nums[l] === target) {
    return l
  }
  return -1
}
//  输入数组可重复,输出最右侧符合条件的值
function searchHasRepateRight(nums, target) {
  let l = 0
  let r = nums.length - 1
  while (l <= r) {
    const mid = Math.floor(l + (r - l) / 2)
    if (nums[mid] <= target) {
      l = mid + 1
    } else {
      r = mid - 1
    }
  }
  console.log({ l, r })
  if (nums[r] === target) {
    return r
  }
  // 没找到
  // l:第一个大于target的索引
  // r:最后一个小于target的索引
  return -1
}
左闭,右开 [l, r)
  1. 输入数组不可重复
  2. 输入数组可重复,输出最左侧符合条件的值
  3. 输入数组可重复,输出最右侧符合条件的值
// 输入数组不可重复
function searchNotRepate(nums, target) {
  let l = 0
  let r = nums.length
  while (l < r) {
    const mid = Math.floor(l + (r - l) / 2)
    if (nums[mid] > target) {
      r = mid
    } else if (nums[mid] < target) {
      l = mid + 1
    } else {
      return l
    }
  }
  console.log({ l, r })
  return -1
}

// 输入数组可重复,最左侧符合条件的值
function searchHasRepateLeft(nums, target) {
  let l = 0
  let r = nums.length
  while (l < r) {
    const mid = Math.floor(l + (r - l) / 2)
    if (nums[mid] < target) {
      l = mid + 1
    } else {
      r = mid
    }
  }
  console.log({ l, r })
  if (nums[l] === target) {
    return l
  }
  return -1
}
//  输入数组可重复,最右侧符合条件的值
function searchHasRepateRight(nums, target) {
  let l = 0
  let r = nums.length
  while (l < r) {
    const mid = Math.floor(l + (r - l) / 2)
    console.log(mid)
    if (nums[mid] <= target) {
      l = mid + 1
    } else {
      r = mid
    }
  }
  console.log({ l, r })
  const index = r - 1
  if (nums[index] === target) {
    return index
  }
  // 没找到
  // l:第一个大于target的索引
  // r:最后一个小于target的索引
  return -1
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 终结条件为根据if (check(mid)) 条件成立,判断答案在左区间还是右区间,如果答案在左区间并且mid也可...
    舒也ella阅读 658评论 0 0
  • 本文介绍了我这半年以来,在刷题过程中使用“二分查找法”刷题的一个模板,包括这个模板的优点、使用技巧、注意事项、调试...
    李威威阅读 5,860评论 0 5
  • 在不重复升序数组查找目标值 解法1 说明:① right的初始值为nums.length-1,表示此次二分查找的区...
    holybell阅读 335评论 0 2
  • 二分查找本身的思路是很简单的,也没有什么弯弯绕绕,什么情况写二分?有序数组+暴力解是一次for循环的情况,基本就是...
    张大铁阅读 604评论 0 0
  • 如果面试时面试官让你写一个二分查找你会怎么写呢?不少同学可能都会这样写 如果面试的时候这样写了,并且其他方面又没有...
    yfyu阅读 89评论 0 0