剑指 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;
}
};
单调队列