|
| 1 | +### 895. Maximum Frequency Stack |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +题目: |
| 6 | +https://leetcode.com/problems/maximum-frequency-stack/ |
| 7 | + |
| 8 | +难度: |
| 9 | +Hard |
| 10 | + |
| 11 | +题意: |
| 12 | + |
| 13 | +1. 一个特殊的类栈数据结构,具有两种操作 |
| 14 | +2. push x:表示将x入栈 |
| 15 | +3. pop:表示将栈中最多的数弹出,相同数量的数弹出最近入栈的一个数 |
| 16 | + |
| 17 | +思路: |
| 18 | + |
| 19 | +- 这个题的数据结构中,x是key,既需要根据x来操作,又需要根据x的数量和入栈时间来出栈,典型的双向查找表 |
| 20 | + |
| 21 | +- 维护一个x到x的入栈时间的映射关系,入栈时间我们定义为第几次push操作,即x->[t1,t2,t3] |
| 22 | + |
| 23 | +- 维护一个**有序**的x的入栈时间到x的对应表,比较函数定义为:栈中元素个数,和栈顶时间 |
| 24 | + |
| 25 | +代码: |
| 26 | + |
| 27 | +```java |
| 28 | +class FreqStack { |
| 29 | + |
| 30 | + int _count; |
| 31 | + private class Item implements Comparable<Item> { |
| 32 | + LinkedList<Integer> time; |
| 33 | + |
| 34 | + public Item(LinkedList<Integer> time) { |
| 35 | + this.time = time; |
| 36 | + } |
| 37 | + |
| 38 | + public LinkedList<Integer> getTime() { |
| 39 | + return time; |
| 40 | + } |
| 41 | + |
| 42 | + @Override |
| 43 | + public int compareTo(Item o) { |
| 44 | + if (time.size() == o.time.size()) { |
| 45 | + return Integer.compare(o.time.getLast(), time.getLast()); |
| 46 | + } else { |
| 47 | + return Integer.compare(o.time.size(), time.size()); |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + TreeMap<Item, Integer> freqToId; |
| 53 | + Map<Integer, Item> idToFreq; |
| 54 | + |
| 55 | + public FreqStack() { |
| 56 | + _count = 0; |
| 57 | + freqToId = new TreeMap<Item, Integer>(); |
| 58 | + idToFreq = new HashMap<Integer, Item>(); |
| 59 | + } |
| 60 | + |
| 61 | + public void push(int x) { |
| 62 | + if (!idToFreq.containsKey(x)) { |
| 63 | + LinkedList<Integer> time = new LinkedList<Integer>(); |
| 64 | + time.addLast(_count++); |
| 65 | + Item item = new Item(time); |
| 66 | + freqToId.put(item, x); |
| 67 | + idToFreq.put(x, item); |
| 68 | + } else { |
| 69 | + Item origin = idToFreq.get(x); |
| 70 | + freqToId.remove(origin); |
| 71 | + LinkedList<Integer> time = origin.time; |
| 72 | + time.addLast(_count++); |
| 73 | + Item item = new Item(time); |
| 74 | + idToFreq.put(x, item); |
| 75 | + freqToId.put(item, x); |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + public int pop() { |
| 80 | + Map.Entry<Item, Integer> first = freqToId.firstEntry(); |
| 81 | + freqToId.remove(first.getKey()); |
| 82 | + idToFreq.remove(first.getValue()); |
| 83 | + |
| 84 | + LinkedList<Integer> time = first.getKey().time; |
| 85 | + time.removeLast(); |
| 86 | + if (time.size() != 0) { |
| 87 | + Item item = new Item(time); |
| 88 | + idToFreq.put(first.getValue(), item); |
| 89 | + freqToId.put(item, first.getValue()); |
| 90 | + } |
| 91 | + |
| 92 | + return first.getValue(); |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
0 commit comments