代码随想录算法训练营第十三天 | 239. 滑动窗口最大值、347. 前 K 个高频元素

62 阅读1分钟

239. 滑动窗口最大值

构建一个单调递减队列,入队时如果元素比之前元素大,就扔掉之前元素,一直到比之前元素小为止,出队时如果队顶元素不是需要出队元素,就不出队,这样每次循环数组时,入队第k个元素,出队第一个元素,然后取队顶元素(最大值)即可

function maxSlidingWindow(nums: number[], k: number): number[] {
  const q = new MonotonicQueue()
  const res: number[] = []
  for (let i = 0; i < k; i++) {
    q.push(nums[i])
  }
  for (let i = 0; i <= nums.length - k; i++) {
    if (i) {
      q.push(nums[i + k - 1])
      q.pop(nums[i - 1])
    }
    res.push(q.front())
  }
  return res
};
class MonotonicQueue {
  private arr: number[]
  constructor() {
    this.arr = []
  }

  push(x: number) {
    while (this.arr.length && this.arr[this.arr.length - 1] < x) {
      this.arr.pop()
    }
    this.arr.push(x)
  }

  pop(x: number) {
    if (this.front() === x) {
      return this.arr.shift()
    }
    return
  }

  front() {
    return this.arr[0]
  }
}

347. 前 K 个高频元素

用map记录每个元素出现的次数,用小顶堆构建一个单调队列,小顶堆还没学到,先用js自带的排序处理

function topKFrequent(nums: number[], k: number): number[] {
  const m: Map<number, number> = new Map()
  for (const x of nums) {
    m.set(x, (m.get(x) || 0) + 1)
  }
  return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, k).map(i => i[0])
}