栈&队列
2020-03-08 本文已影响0人
juriau
一、栈&队列总结
- 栈/队列的应用
- 接雨水
- 验证栈序列
- 滑动窗口的最大值
- 栈/队列的特殊实现
- 用两个栈实现队列
- 用两个队列实现栈
- 特殊栈/队列
- 最大队
- 最小栈
二、栈&队列题目
接雨水
题目描述:
方法1:暴力法
对于数组中的每个元素,我们找出下雨后水能达到的最高位置,等于两边最大高度的较小值减去当前高度的值。
方法2:栈的应用
每遇到一次当前元素比栈顶元素大,说明可能有可以积水的坑;
弹出栈顶元素作为mid,当前元素为r,此时的栈顶元素为l,以此计算当前坑的容积。
int trap(vector<int>& height)
{
int ans = 0;
stack<int> st;
for (int i = 0; i < height.size(); i++){
while (!st.empty() && height[st.top()] < height[i]) {
int mid = st.top(); st.pop();
if (st.empty())
break;
int l = st.top(), r = i;
int curWidth = r - l - 1;
int curHeight = min(height[l], height[r]) - height[mid];
ans += curWidth * curHeight;
}
st.push(i);
}
return ans;
}
验证栈序列
思路:
遍历pushed数组,在遍历的过程中将pushed数组元素压入栈中;
如果当前栈顶元素与poped数组索引j相同,循环弹出;
最后遍历完数组之后,查看索引j是否到达poped数组最后,如果没有,返回false。
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> s;
int j = 0;
for(int i=0; i<pushed.size(); i++){
s.push(pushed[i]);
while (!s.empty() && s.top() == popped[j]) {
j++;
s.pop();
}
}
if (j < popped.size()) {
return false;
}
return true;
}
};
滑动窗口的最大值
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
deque<int> q; // 队列的队首元素 始终 指向滑动窗口最大的数
q.push_back(0);
for (int i=1; i<k; i++) {
while (!q.empty() && nums[i] > nums[q.back()]) {
q.pop_back();
}
q.push_back(i);
}
res.push_back(nums[q.front()]);
for (int i=k; i<nums.size(); i++) {
// 如果队首元素不在滑动窗口范围内
if(i - q.front() == k){
q.pop_front();
}
// 处理移动窗口的新数据
while (!q.empty() && nums[i] > nums[q.back()]) {
q.pop_back();
}
q.push_back(i);
res.push_back(nums[q.front()]);
}
return res;
}
栈 & 队列的特殊实现
用栈实现队列
typedef struct {
Stack* s1; // 负责进数据
Stack* s2; // 负责出数据
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
q->s1 = createStack();
q->s2 = createStack();
return q;
}
bool myQueueEmpty(MyQueue* obj) {
return isEmpty(obj->s1) && isEmpty(obj->s2);
}
void myQueuePush(MyQueue* obj, int x) {
push(obj->s1, x);
}
int myQueuePop(MyQueue* obj) {
if(myQueueEmpty(obj)){
return INT_MIN;
}
if(isEmpty(obj->s2)){
while(!isEmpty(obj->s1)){
push(obj->s2, pop(obj->s1));
}
}
return pop(obj->s2);
}
用队列实现栈
typedef struct {
Queue* q1;
Queue* q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* s = (MyStack*)malloc(sizeof(MyStack));
s->q1 = createQueue();
s->q2 = createQueue();
return s;
}
void myStackPush(MyStack* obj, int x) {
if (!isEmpty(obj->q1)) {
enqueue(obj->q1, x);
}else {
enqueue(obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
if (!isEmpty(obj->q1)) {
while (obj->q1->size > 1) {
enqueue(obj->q2, dequeue(obj->q1));
}
return dequeue(obj->q1);
}else{
while (obj->q2->size > 1) {
enqueue(obj->q1, dequeue(obj->q2));
}
return dequeue(obj->q2);
}
}
特殊栈 & 队列
最小栈
#define MAX 12048
typedef struct {
int data[MAX];
int top;
int min[MAX];
} MinStack;
MinStack* minStackCreate() {
MinStack* s = (MinStack*)malloc(sizeof(MinStack));
s->top = -1;
return s;
}
int minStackGetMin(MinStack* obj) {
return obj->min[obj->top];
}
void minStackPush(MinStack* obj, int x) {
if(obj->top == -1){
obj->min[++obj->top] = x;
}else{
int curMinVal = minStackGetMin(obj);
if (x < curMinVal) {
obj->min[++obj->top] = x;
}else{
obj->min[++obj->top] = curMinVal;
}
}
obj->data[obj->top] = x;
}
void minStackPop(MinStack* obj) {
obj->top--;
}
int minStackTop(MinStack* obj) {
return obj->data[obj->top];
}
void minStackFree(MinStack* obj) {
free(obj);
}
class MinStack {
private:
stack<int> data;
stack<int> minStack; // 栈顶是最小值
public:
MinStack() {
}
void push(int x) {
data.push(x);
if (minStack.empty() || x <= minStack.top()) {
minStack.push(x);
}
}
void pop() {
if (minStack.top() == data.top()) {
minStack.pop();
}
data.pop();
}
int top() {
return data.top();
}
int getMin() {
return data.top();
}
};
最大队
class MaxQueue {
private:
queue<int> que;
deque<int> dq; // 队首是最大值
public:
MaxQueue() {
}
int max_value() {
if(dq.empty()) return -1;
return dq.front();
}
void push_back(int value) {
que.push(value);
while (!dq.empty() && value > dq.back())
dq.pop_back();
dq.push_back(value);
}
int pop_front() {
if(que.empty()) return -1;
int val = que.front();
que.pop();
if (val == dq.front()) dq.pop_front();
return val;
}
};