0895. Maximum Frequency Stack (H)

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 integer x 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 that 0 <= 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 exceed 10000 in a single test case.
  • The total number of FreqStack.pop calls will not exceed 10000 in a single test case.
  • The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases.

题意

实现一个类似栈的数据结构的两种操作:

  1. push,将一个新值加入到结构中
  2. 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;
    }
}
原文地址:https://www.cnblogs.com/mapoos/p/14459695.html