剑指 Offer 09. 用两个栈实现队列

思路很简单,栈1用来进队,栈2用来出队
入队操作:
- 将元素压入栈1
出队操作:
- 如果两个栈都空,那么返回-1
- 判断栈2是否为空:
- 空:将栈1中的所有元素导入栈2,返回栈2的栈顶元素并弹出
- 不空:返回栈2的栈顶元素并弹出
class CQueue {public:CQueue() {}void appendTail(int value) {st1.push(value);}int deleteHead() {if (st2.empty() && st1.empty())return -1;if (st2.empty()) {while (!st1.empty()) {st2.push(st1.top());st1.pop();}}int temp = st2.top();st2.pop();return temp;}stack<int> st1;stack<int> st2;};/*** Your CQueue object will be instantiated and called as such:* CQueue* obj = new CQueue();* obj->appendTail(value);* int param_2 = obj->deleteHead();*/
剑指 Offer 30. 包含min函数的栈
思路一:单调栈辅助
因为要求维护栈中的最小值,并且要求min函数的时间复杂度为O(1),那么可以用一个单调栈来维护栈中的最小元素,单调栈的栈顶始终是栈的最小元素
push:
- st1正常操作
- 如果st2的栈顶元素大于等于x(取等号是因为可能有两个相同的最小值),那么将x压入栈2,相当于更新最小值(st2的栈顶),否则不操作
pop:
- 如果两个栈的栈顶相同,弹出的是最小值,此时需要将两个栈的栈顶都弹出,否则只弹出st1的栈顶元素
top:
- st1.top()
min:
- st2.top()
class MinStack {public:/** initialize your data structure here. */MinStack() {}void push(int x) {st1.push(x);if (st2.empty() || st2.top() >= x) {st2.push(x);}}void pop() {if (st2.top() == st1.top())st2.pop();st1.pop();}int top() {return st1.top();}int min() {return st2.top();}stack<int> st1;stack<int> st2; // 单调栈,栈顶是最小元素};/*** Your MinStack object will be instantiated and called as such:* MinStack* obj = new MinStack();* obj->push(x);* obj->pop();* int param_3 = obj->top();* int param_4 = obj->min();*/
思路二:保存两个值
1.先存x,再存最小值
每当push时,先将x放入,在存储一个当前最小值
class MinStack {public:/** initialize your data structure here. */int Min=INT_MAX;stack<int> st;MinStack() {}void push(int x) {st.push(Min);//加入上一个最小值if(x<Min) Min=x;//更新最小值st.push(x);//加入该数值}void pop() {st.pop();//pop掉该数值Min=st.top();//得到去掉该值后的最小值st.pop();//将该最小值也pop掉}int top() {return st.top();//返回栈顶即可}int min() {return Min;}};/*** Your MinStack object will be instantiated and called as such:* MinStack* obj = new MinStack();* obj->push(x);* obj->pop();* int param_3 = obj->top();* int param_4 = obj->min();*/
2. 我的思路:先存x,再存min
栈中的元素是成对的,表示存入x后,栈中的最小元素是min
class MinStack {
public:
/** initialize your data structure here. */
stack<int> st;
MinStack() {}
void push(int x) {
if (st.empty()) { // 如果栈为空,当前值就是最小值
st.push(x);
st.push(x);
} else {
int curMin = st.top(); // 当前最小值
st.push(x);
if (x < curMin) {
st.push(x);
} else {
st.push(curMin);
}
}
}
void pop() {
if (st.empty())
return;
st.pop();//pop掉最小值
st.pop();//将该值也pop掉
}
int top() {
if (st.empty())
return -1;
int temp1 = st.top();
st.pop();
int temp2 = st.top();
st.push(temp1);
return temp2;
}
int min() {
return st.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
剑指 Offer 31. 栈的压入、弹出序列

思路:
用一个辅助栈
如果栈为空或者栈顶元素不等于当前待出栈元素,那么不断将pushed元素压入栈中,如果元素用光还是无法找到待出栈元素,那么返回false
如果栈顶元素和待出栈元素一致,那么将该元素从辅助栈中弹出,访问下一个待出栈元素
所有元素都出栈以后,返回true
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> st;
int i = 0, j = 0;
while (i < popped.size()) {
while (st.empty() || st.top() != popped[i]) {
if (j == pushed.size())
break;
st.push(pushed[j++]);
}
if (st.top() != popped[i])
break;
st.pop();
i++;
}
return i == popped.size();
}
};
剑指 Offer 59 - I. 滑动窗口的最大值

优先队列
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if (nums.size() == 0) return {};
priority_queue<pair<int, int>> pq;
for (int i = 0; i < k; ++i) {
pq.emplace(nums[i], i);
}
vector<int> res;
res.push_back(pq.top().first);
for (int i = k; i < nums.size(); ++i) {
pq.emplace(nums[i], i);
while (pq.top().second <= i - k) {
pq.pop();
}
res.push_back(pq.top().first);
}
return res;
}
};
单调队列
剑指 Offer 59 - II. 队列的最大值

