Problem
實現 FreqStack
,模擬類似棧的資料結構的操作的一個類。
FreqStack
有兩個函式:
push(int x)
,將整數x
推入棧中。pop()
,它移除並返回棧中出現最頻繁的元素。- 如果最頻繁的元素不只一個,則移除並返回最接近棧頂的元素。
示例:
輸入:
["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
輸出:[null,null,null,null,null,null,null,5,7,5,4]
解釋:
執行六次 .push 操作後,棧自底向上為 [5,7,5,7,4,5]。然後:
pop() -> 返回 5,因為 5 是出現頻率最高的。
棧變成 [5,7,5,7,4]。
pop() -> 返回 7,因為 5 和 7 都是頻率最高的,但 7 最接近棧頂。
棧變成 [5,7,5,4]。
pop() -> 返回 5 。
棧變成 [5,7,4]。
pop() -> 返回 4 。
棧變成 [5,7]。
Solution
這道題目我使用了兩個雜湊表:
Freq
用來統計數字出現的次數: integer
->unsigned
FreqStack
用來統計出現次數所對應的棧:unsigned
->stack<int>
主要的解法是為每次出現第幾次的元素建一個棧,比如
1,3,4,5,1,1,
那麼1,3,4,5
就會在FreqStack[1]
上因為他們的出現次數為1
而第二次出現的1
就會壓入FreqStack[2]
,第三次出現的1
會出現在FreqStack[3]
,以此類推。
在Freq
雜湊表的輔助下,判斷出現次數會相當容易。AC程式碼如下
class FreqStack {
public:
void push(int x) {
Freq[x]++;
maxfreq = max(Freq[x], maxfreq);
FreqStack[Freq[x]].push(x);
}
int pop() {
int x = FreqStack[maxfreq].top();
FreqStack[maxfreq].pop();
if(FreqStack[Freq[x]].empty())
maxfreq--;
Freq[x]--;
return x;
}
private:
unordered_map<int, unsigned> Freq;
unordered_map<unsigned, stack<int>> FreqStack;
unsigned maxfreq = 0;
};