二分查找

大体分为两种写法
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
}

你可能感兴趣的:(二分查找)