可取最大值的栈
再用个maxs栈保存当前nums栈的最大值。
class MaxStack {
stack<int> nums;
stack<int> maxs;
public:
/** initialize your data structure here. */
MaxStack() {
}
void push(int x) {
if (maxs.empty() || x >= maxs.top()) maxs.push(x);
nums.push(x);
}
int pop() {
if (nums.top() == maxs.top()) maxs.pop();
int ans = top(); nums.pop();
return ans;
}
int top() {
return nums.top();
}
int peekMax() {
return maxs.top();
}
int popMax() {
int ans = peekMax();
stack<int> buffer;
while (top() != ans) {
buffer.push(pop());
}
maxs.pop();
nums.pop();
while (!buffer.empty()) {
push(buffer.top());
buffer.pop();
}
return ans;
}
};
扩展:可取最大值的队列
用到最大值放队头的"单调递减队列",见单调队列
频率栈
按频率分桶,类似O(1)时间修改问题,但频率增加时小频率项保留
class FreqStack {
// 每个频率一个桶;"有多个最大频率时,后进先出",所以该桶是栈,栈中存放该频率的数
unordered_map<int, stack<int>> buckets; // freq=>stack
unordered_map<int, int> freq; // num=>freq
int maxfreq = 0;
public:
FreqStack() {
}
void push(int x) {
buckets[++freq[x]].push(x);
if (freq[x] > maxfreq) maxfreq = freq[x];
}
int pop() {
int x = buckets[maxfreq].top(); buckets[maxfreq].pop();
freq[x]--;
if (buckets[maxfreq].empty()) maxfreq--;
return x;
}
};
只用栈操作,把栈排序成栈顶最小的递减序列
void sort(stack<int> &A) {
// 先把B排成递增序列 <=> 找下一个更小的数
stack<int> B;
while (!A.empty()) {
int a = A.top(); A.pop();
while (!B.empty() && a < B.top()) {
A.push(B.top());
B.pop();
}
B.push(a);
}
// 把B倒回A
while (!B.empty()) {
A.push(B.top());
B.pop();
}
}