美文网首页
栈&队列

栈&队列

作者: juriau | 来源:发表于2020-03-08 15:35 被阅读0次

一、栈&队列总结

  • 栈/队列的应用
    • 接雨水
    • 验证栈序列
    • 滑动窗口的最大值
  • 栈/队列的特殊实现
    • 用两个栈实现队列
    • 用两个队列实现栈
  • 特殊栈/队列
    • 最大队
    • 最小栈

二、栈&队列题目

接雨水

题目描述:

方法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;
    }
};

相关文章

  • Algorithm小白入门 -- 队列和栈

    队列和栈队列实现栈、栈实现队列单调栈单调队列运用栈去重 1. 队列实现栈、栈实现队列 队列是一种先进先出的数据结构...

  • 栈和队列

    用栈定义队列(出入栈) 用队列定义栈(数据队列和辅助队列)

  • 数据结构——栈和队列

    用数组实现栈和队列 用栈实现队列 用队列实现栈 栈和队列的经典算法题最小间距栈宠物收养所 数组实现栈和队列 用数组...

  • Swift 队列&栈 相关操作

    栈 LIFO(后进先出) 队列 FIFO(先进先出) 队列与栈相互的实现 栈 - 队列实现 队列 - 栈实现 相关...

  • 栈和队列

    栈和队列 本质上是稍加限制的线性表 栈和队列定义 栈顺序栈定义 链栈结点定义 队列顺序队列 链队列链队类型定义 链...

  • 算法-栈和队列算法总结

    栈和队列算法总结 1 模拟 1.1 使用栈实现队列 1.2 使用队列实现栈 2 栈的应用 2.1 栈操作 2.2 ...

  • 栈&队列

    一、栈&队列总结 栈/队列的应用接雨水验证栈序列滑动窗口的最大值 栈/队列的特殊实现用两个栈实现队列用两个队列实现...

  • 算法分析 [BFS、Greedy贪心] 2019-02-18

    队列 和 栈 232. 用栈实现队列 Implement Queue using Stacks双栈,出队列时,将i...

  • 队列之-队列实现栈

    一、队列实现栈核心算法概述 之前已经描述过了用栈实现队列的功能,见栈系列之-实现队列,那么同样队列也可以用来实现栈...

  • 数据结构 | 其三 栈和队列

    栈 java中栈继承了Vector 队列 2.1 普通队列 2.2 循环队列 2.3 优先级队列 2.4 阻塞队列...

网友评论

      本文标题:栈&队列

      本文链接:https://www.haomeiwen.com/subject/oulddhtx.html