Last Updated on 2022-03-19 by Clay
題目
Design a stack-like data structure to push elements to the stack and pop the most frequent element from the stack.
Implement the FreqStack
class:
FreqStack()
constructs an empty frequency stack.void push(int val)
pushes an integerval
onto the top of the stack.int pop()
removes and returns the most frequent element in the stack.- If there is a tie for the most frequent element, the element closest to the stack's top 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 FreqStack freqStack = new FreqStack(); freqStack.push(5); // The stack is [5] freqStack.push(7); // The stack is [5,7] freqStack.push(5); // The stack is [5,7,5] freqStack.push(7); // The stack is [5,7,5,7] freqStack.push(4); // The stack is [5,7,5,7,4] freqStack.push(5); // The stack is [5,7,5,7,4,5] freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,5,7,4]. freqStack.pop(); // return 7, as 5 and 7 is the most frequent, but 7 is closest to the top. The stack becomes [5,7,5,4]. freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,4]. freqStack.pop(); // return 4, as 4, 5 and 7 is the most frequent, but 4 is closest to the top. The stack becomes [5,7].
Constraints:
0 <= val <= 109
- At most
2 * 104
calls will be made topush
andpop
. - It is guaranteed that there will be at least one element in the stack before calling
pop
.
題目要我們設計一個類似 stack 的結構,不過若要彈出(pop),則必須要按照數值的頻率來排優先度;若是頻率一樣的數值,則像 stack 一樣越接近頂部越優先彈出。
解題思路
Hash Map 解法
老實說這題還滿容易就 TLE 了,所以比較簡單的做法應該是使用 hash map 來紀錄一個數值的出現次數、以及特定頻率下數值推入的順序。
如果彈出了數值,則需要把該數值對應的出現次數減去一、並將對應最高頻率的順序表彈出。
並且還需要一個紀錄最大出現次數的變數,並在彈出後檢查最大頻率的順序表是否為空;最大頻率對應的順序表若為空,則將最大頻率的變數減去一。
詳細的製作方法請參考程式碼。
C++ 範例程式碼
class FreqStack {
public:
// Init
int maxFreq = 0;
unordered_map<int, int> val2freq;
unordered_map<int, stack<int>> freq2stack;
FreqStack() {
}
// Push09sxaz
void push(int val) {
++val2freq[val];
maxFreq = max(maxFreq, val2freq[val]);
freq2stack[val2freq[val]].push(val);
}
int pop() {
// Get the top value
int top = freq2stack[maxFreq].top();
freq2stack[maxFreq].pop();
// Decrement the frquency of the top value (for the next push)
--val2freq[top];
// If the maxFreq stack has no any value
if (freq2stack[maxFreq].empty()) --maxFreq;
return top;
}
};
/**
* Your FreqStack object will be instantiated and called as such:
* FreqStack* obj = new FreqStack();
* obj->push(val);
* int param_2 = obj->pop();
*/
兩節點 Python 範例程式碼
class FreqStack:
def __init__(self):
self.max_freq = 0
self.val2freq = dict()
self.freq2stack = dict()
def push(self, val: int) -> None:
freq = self.val2freq.get(val, 0) + 1
self.val2freq[val] = freq
self.max_freq = max(self.max_freq, freq)
self.freq2stack[freq] = self.freq2stack.get(freq, []) + [val]
def pop(self) -> int:
top = self.freq2stack[self.max_freq].pop()
self.val2freq[top] -= 1
if len(self.freq2stack[self.max_freq]) == 0:
self.max_freq -= 1
return top
# Your FreqStack object will be instantiated and called as such:
# obj = FreqStack()
# obj.push(val)
# param_2 = obj.pop()