[路飞]_前端算法第八十一弹-前 K 个高频元素

74 阅读1分钟

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入:nums = [1,1,1,2,2,3], k = 2
输出:[1,2]

示例 2:

输入:nums = [1], k = 1
输出:[1]

这道题我们用到了大顶堆,我们先用map将数字的个数进行统计,然后加入大顶堆中,再返回k次堆顶元素即可。

var topKFrequent = function (nums, k) {
  let map = new Map();
  let heap = new Heap((a, b) => a.val < b.val)
  let res = []
  for (let i = 0; i < nums.length; i++) {
    map.set(nums[i], map.has(nums[i]) ? map.get(nums[i]) + 1 : 1)
  }
  map.forEach((val, key) => {
    heap.push({
      key, val
    })
  })
  for (let i = 0; i < k; i++) {
    res.push(heap.pop().key)
  }

  return res
};

通用堆写法

class Heap {
    constructor(cmp = "large") {
        if (cmp == "large") {
            this.cmp = this.large;
        } else if (cmp == "small") {
            this.cmp = this.small
        } else {
            this.cmp = cmp
        }
        this.res = [];
        this.cnt = 0;
    }

    push(val) {
        this.cnt++;
        this.res.push(val)
        this.shiftUp(this.cnt - 1)
    }

    pop() {
        this.cnt--;
        const res = this.res[0]
        const pop = this.res.pop()
        if (this.cnt) {
            this.res[0] = pop
            this.shiftDown(0)
        }
        return res
    }

    shiftUp(i) {
        if (i === 0) return
        const par = this.getParentIndex(i)
        if (this.cmp(this.res[par], this.res[i])) {
            this.swap(par, i)
            this.shiftUp(par)
        }
    }

    shiftDown(i) {
        const l = this.getLeftIndex(i)
        const r = this.getRightIndex(i)
        if (l < this.cnt && this.cmp(this.res[i], this.res[l])) {
            this.swap(i, l)
            this.shiftDown(l)
        }
        if (r < this.cnt && this.cmp(this.res[i], this.res[r])) {
            this.swap(i, r)
            this.shiftDown(r)
        }
    }

    getParentIndex(i) {
        return (i - 1) >> 1
    }

    getLeftIndex(i) {
        return i * 2 + 1
    }

    getRightIndex(i) {
        return i * 2 + 2
    }

    large = (a, b) => a < b

    small = (a, b) => a > b;

    swap = (i, j) => [this.res[i], this.res[j]] = [this.res[j], this.res[i]];

    top = () => this.res[0];

    size = () => this.cnt;

    isEmpty = () => this.cnt === 0

}