代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素

161 阅读1分钟

704. 二分查找

左闭右闭区间,middle取中间值向下取整

function search(nums: number[], target: number): number {
  let l = 0
  let r = nums.length - 1
  while (l <= r) {
    const m = l + Math.floor((r - l) / 2)
    if (nums[m] === target) {
      return m
    } else if (nums[m] > target) {
      r = m - 1
    } else {
      l = m + 1
    }
  }
  return -1
};

27. 移除元素

快慢指针,慢指针用来放置非val元素,快指针遍历数组

function removeElement(nums: number[], val: number): number {
  let s = 0
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] !== val) {
      nums[s] = nums[i]
      s++
    }
  }
  return s
};

35. 搜索插入位置

先处理最左边和最右边两种边界情况,剩下一种插入中间的情况时,插入位置一定是l,因为此时l>r,l在m的右边

function searchInsert(nums: number[], target: number): number {
  let l = 0
  let r = nums.length - 1
  if (target < nums[l]) {
    return 0
  } else if (target > nums[r]) {
    return r + 1
  }
  while (l <= r) {
    const m = l + Math.floor((r - l) / 2)
    if (nums[m] === target) {
      return m
    } else if (nums[m] > target) {
      r = m - 1
    } else {
      l = m + 1
    }
  }
  return l
};

34. 在排序数组中查找元素的第一个和最后一个位置

两次二分查找,第一次找第一个元素的位置,第二次找最后一个元素的位置,找第一个就是不停缩小r,找最后一个就是不停缩小l

function searchRange(nums: number[], target: number): number[] {
  let first = -1
  let last = -1
  let l = 0
  let r = nums.length - 1
  while (l <= r) {
    const m = l + Math.floor((r - l) / 2)
    if (nums[m] === target) {
      first = m
      r = m - 1 // 重点
    } else if (nums[m] > target) {
      r = m - 1
    } else {
      l = m + 1
    }
  }
  l = 0
  r = nums.length - 1
  while (l <= r) {
    const m = l + Math.floor((r - l) / 2)
    if (nums[m] === target) {
      last = m
      l = m + 1 // 重点
    } else if (nums[m] > target) {
      r = m - 1
    } else {
      l = m + 1
    }
  }
  return [first, last]
};