LeetCode 记录-895. 最大频率栈

135 阅读2分钟

LeetCode 记录-895. 最大频率栈

我的解法

思路

image.png

涉及到频率,我的想法就是用一个哈希表去计算每个数字出现的次数,然后每次 pop 时,按次数倒序排列,因为可能存在频率相同的数字,所以从头开始找出现次数相同的数字;同时,我也会在 push 的时候维护一个队列,里面会保持数字出现的顺序,所以在 pop 时,当拿到一个或多个频率相同的数字时,按出现的顺序遍历队列,直到找到符合频率最高的那个数字,将哈希表中对应的频率减 1,同时移除队列中的对应下表的数字,最后返回这个数字。

思路应该是正确的,但是时间复杂度太高了,后面用例超时了。

代码

var FreqStack = function () {
  this.queue = [];
  this.freqMap = new Map([]);
};

/**
 * @param {number} val
 * @return {void}
 */
FreqStack.prototype.push = function (val) {
  this.queue.push(val);
  this.freqMap.set(val, (this.freqMap.get(val) || 0) + 1);
};

/**
 * @return {number}
 */
FreqStack.prototype.pop = function () {
  const maxFreqNumArr = [];
  const sortedEntries = [...this.freqMap.entries()].sort(
    (entry1, entry2) => entry2[1] - entry1[1]
  );

  const maxCount = sortedEntries[0][1];
  maxFreqNumArr.push(sortedEntries[0][0]);

  for (let i = 1; i < sortedEntries.length; i++) {
    if (maxCount === sortedEntries[i][1]) {
      maxFreqNumArr.push(sortedEntries[i][0]);
    }
  }

  for (let i = this.queue.length - 1; i >= 0; i--) {
    const val = this.queue[i];
    if (maxFreqNumArr.indexOf(val) !== -1) {
      this.queue.splice(i, 1);
      this.freqMap.set(val, this.freqMap.get(val) - 1);
      return val;
    }
  }
};

复杂度分析(自我分析,不一定对)

时间复杂度

对于 push:O(1)O(1)

对于 pop:O(nlogn)O(nlogn):其中 n 为 FreqStack 中元素的个数,排序的时间复杂度为O(nlogn)O(nlogn),后面两次遍历在最差情况下的时间复杂度都为O(n)O(n),所以总的时间复杂度为O(nlogn)O(nlogn)

空间复杂度

O(n)O(n),其中 n 为 FreqStack 中元素的个数。


官方解法 1: 哈希表和栈

思路

官方也是采用哈希表的思路,但官方采用了第二个存出现频率相同数字的栈的哈希表以及一个存当前最大频率的变量来处理优先弹出插入最晚且频率最大的元素的要求。官方思路如下:

image.png

代码

var FreqStack = function () {
  this.freq = new Map();
  this.group = new Map();
  this.maxFreq = 0;
};

FreqStack.prototype.push = function (val) {
  this.freq.set(val, (this.freq.get(val) || 0) + 1);
  if (!this.group.has(this.freq.get(val))) {
    this.group.set(this.freq.get(val), []);
  }
  this.group.get(this.freq.get(val)).push(val);
  this.maxFreq = Math.max(this.maxFreq, this.freq.get(val));
};

FreqStack.prototype.pop = function () {
  const val = this.group.get(this.maxFreq)[
    this.group.get(this.maxFreq).length - 1
  ];
  this.freq.set(val, this.freq.get(val) - 1);
  this.group.get(this.maxFreq).pop();

  if (this.group.get(this.maxFreq).length === 0) {
    this.maxFreq--;
  }
  return val;
};

复杂度分析

时间复杂度

O(1)O(1),使用了两层for循环。

空间复杂度

O(n)O(n),其中 n 为 FreqStack 中元素的个数。