Maximum Frequency Stack (H)
题目
Implement FreqStack
, a class which simulates the operation of a stack-like data structure.
FreqStack
has two functions:
push(int x)
, which pushes an integerx
onto the stack.- pop(), which removes and returns the most frequent element in the stack.
- If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned.
Example 1:
Input:
["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
Output: [null,null,null,null,null,null,null,5,7,5,4]
Explanation:
After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then:
pop() -> returns 5, as 5 is the most frequent.
The stack becomes [5,7,5,7,4].
pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.
The stack becomes [5,7,5,4].
pop() -> returns 5.
The stack becomes [5,7,4].
pop() -> returns 4.
The stack becomes [5,7].
Note:
- Calls to
FreqStack.push(int x)
will be such that0 <= x <= 10^9
. - It is guaranteed that
FreqStack.pop()
won't be called if the stack has zero elements. - The total number of
FreqStack.push
calls will not exceed10000
in a single test case. - The total number of
FreqStack.pop
calls will not exceed10000
in a single test case. - The total number of
FreqStack.push
andFreqStack.pop
calls will not exceed150000
across all test cases.
题意
实现一个类似栈的数据结构的两种操作:
- push,将一个新值加入到结构中
- pop,返回结构中出现频率最大的数,如果有两个这样的数,则返回后加入的那个数
思路
个人做法是维护一个优先队列pq,将其内部的排序规则指定为题目中的规则。每次push先从pq中删去对应的结点(如果存在),更新后再将结点重新加入pq中;每次pop则从pq头部取结点,处理后返回值。
官方的方法是维护两个HashMap,一个映射 数x->出现频率,一个映射 出现频率->出现对应频率的数组成的栈(后加入的更靠近栈顶)。
代码实现
Java
HashMap+PriorityQueue
class FreqStack {
private Queue<Item> pq;
private Map<Integer, Item> map;
private int cnt = -1;
public FreqStack() {
pq = new PriorityQueue<Item>((a, b) -> {
if (a.freq == b.freq) {
return b.stack.peek() - a.stack.peek();
} else {
return b.freq - a.freq;
}
});
map = new HashMap<>();
}
public void push(int x) {
map.putIfAbsent(x, new Item(x));
Item item = map.get(x);
pq.remove(item);
item.freq += 1;
item.stack.push(++cnt);
pq.offer(item);
}
public int pop() {
Item item = pq.poll();
item.freq -= 1;
item.stack.pop();
if (item.freq != 0) {
pq.offer(item);
}
return item.val;
}
class Item {
int val = 0;
int freq = 0;
Deque<Integer> stack = new ArrayDeque<>();
Item(int x) {
val = x;
}
}
}
HashMap+Stack
class FreqStack {
private Map<Integer, Integer> freq;
private Map<Integer, Deque<Integer>> group;
private int maxFreq;
public FreqStack() {
freq = new HashMap<>();
group = new HashMap<>();
}
public void push(int x) {
int newFreq = freq.getOrDefault(x, 0) + 1;
maxFreq = Math.max(maxFreq, newFreq);
freq.put(x, newFreq);
group.putIfAbsent(newFreq, new ArrayDeque<>());
group.get(newFreq).push(x);
}
public int pop() {
int x = group.get(maxFreq).pop();
freq.put(x, freq.get(x) - 1);
if (group.get(maxFreq).isEmpty()) maxFreq--;
return x;
}
}