题目
Implement FreqStack, a class which simulates the operation of a stack-like data structure.
FreqStack has two functions:
push(int x), which pushes an integerxonto 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.pushcalls will not exceed10000in a single test case. - The total number of
FreqStack.popcalls will not exceed10000in a single test case. - The total number of
FreqStack.pushandFreqStack.popcalls will not exceed150000across 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;}}
