代码随想录第10天 | 栈与队列part01

题目:232.用栈实现队列

思路:

1.使用双栈,一个作为输入,一个作为输出

代码:

class MyQueue {
private:
    stack<int> A,B;
public:
    MyQueue() {
    }
    void push(int x) {
        A.push(x);
    }
    int pop() {  //删除A栈底元素 并返回元素
        int result=this->peek();
        B.pop();
        return result;
    }    
    int peek() {  //获取A栈底元素
        if(B.empty()){
            while(!A.empty()){
                B.push(A.top());
                A.pop();
            }
        }
        return B.top();
    }
    bool empty() {//优化-> return A.empty()&& B.empty;
        if(A.empty()&&B.empty())
            return true;
        else
            return false;    
    }
};

补充:

1.栈和队列是STL(C++标准库)里面的两个数据结构。常使用SGI STL版(开源,可读性高,被GCC所采用)。
2.二者以底层容器来实现所有工作,对外提供统一接口,所以二者不是容器,属于container adapter 容器适配器。
3.因二者的进出特性,不提供迭代器进行访问。
栈stack
stack<类型> 变量名;

  1. 一头通,先进后出
  2. 底层实现可使用容器deque,vector,list,没有指定底层实现,默认deque为缺省情况下栈的底层结构
    deque是一个双向队列,封住一段,只开通另一端就可以实现栈的逻辑了。
  3. 对外提供接口
    push(x) -- 元素 x 入栈、
    empty() -- 返回栈是否为空
    pop() -- 移除栈顶元素
    top() -- 获取栈顶元素
    size() -- 返回栈内元素的大小;
可以指定vector为栈的底层实现,初始化语句如下:
std::stack<int, std::vector<int> > third;  // 使用vector为底层容器的栈

队列queue

  1. 两头通,先进先出
  2. SGI STL中队列一样是以deque为缺省情况下的底部结构
  3. 对外提供接口
    push(x) -- 在末尾加入一个元素
    empty() -- 如果队列空则返回真
    front() -- 返回第一个元素
    pop() -- 删除第一个元素
    back() -- 返回最后一个元素
    size() -- 返回队列中元素的个数
可以指定list 为起底层实现,初始化queue的语句如下:
std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列

题目:225. 用队列实现栈

思路:

0.两个队列,第二个用来备份除队尾元素以外的元素
1.两个队列,入队的时候不断调整,使的后存入的元素在队首 模拟栈的存入
2.一个队列实现,头插尾 ,一直插,最后尾为首 弹出

代码:

方法一

class MyStack {
private:
    queue<int> queueA,queueB;
public:
    MyStack() {
    }
    void push(int x) {  //输入调整,使得队首为最新加入的元素 模拟栈
        queueB.push(x);
        while(!queueA.empty()){
            queueB.push(queueA.front());
            queueA.pop();
        }
        while(!queueB.empty()){
            queueA.push(queueB.front());
            queueB.pop();
        }
    }
    int pop() { //移除并返回队首元素
        int result=queueA.front();
        queueA.pop();
        return result;
    }    
    int top() {//返回队首元素
        return queueA.front();
    }   
    bool empty() {
        return queueA.empty();
    }
}; *

方法二
来源随想录

class MyStack {
public:
    queue<int> que1;
    queue<int> que2; // 辅助队列,用来备份
    /** Initialize your data structure here. */
    MyStack() {

    }
    /** Push element x onto stack. */
    void push(int x) {
        que1.push(x);
    }
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int size = que1.size();
        size--;
        while (size--) { // 将que1 导入que2,但要留下最后一个元素
            que2.push(que1.front());
            que1.pop();
        }
        int result = que1.front(); // 留下的最后一个元素就是要返回的值
        que1.pop();
        que1 = que2;            // 再将que2赋值给que1
        while (!que2.empty()) { // 清空que2
            que2.pop();
        }
        return result;
    }
    /** Get the top element. */
    int top() {
        return que1.back();
    }
    /** Returns whether the stack is empty. */
    bool empty() {
        return que1.empty();
    }
};

题目:20. 有效的括号

思路:

0.利用栈存入,遇到不同边的的括号就弹出,左括号添加,右括号弹出

坑:

  1. 缺少 第一个为右括号的情况 即没有匹配的括号,此时stack为空
  2. stack有empty()判空
  3. 不匹配的情况可以合并一下
class Solution {
public:
    bool isValid(string s) {
        //奇数 直接false
        if(s.size()%2!=0)
            return false;
        stack <char> stack;
        for(char c: s){
            //入栈时直接存入对应的右括号 方便比较
            if(c=='(')  stack.push(')');
            else if(c=='{')  stack.push('}');
            else if(c=='[')  stack.push(']');
            else if(c==')'||c=='}'||c==']'){
                //不通过,缺少第一个为右括号的情况, 优化一下,合并不相等的情况
                if(stack.size()==0||c!=stack.top()) 
                    return false;
                if(c==stack.top())
                    stack.pop();
            }
        }
        return stack.empty();
        /* 啰嗦,已经有empty了啊
        if(stack.size()==0) 
            return true;
        else 
            return false;
        */
    }
};

题目:1047. 删除字符串中的所有相邻重复项

思路:

  1. 利用栈,比较存入元素和栈顶元素是否相等,相等删除,最后将栈内的结果存入新的字符串中,别忘了翻转,栈是后进先出
    时间复杂度: O(n)
    空间复杂度: O(n)

坑:

  1. reveres();
class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> stack;
        for(char c: s){
            if(stack.size()!=0&&c==stack.top())
                stack.pop();
            else 
                stack.push(c);
        }
        //啊哈,栈存入字符串是倒序,那么翻转就解决了
        string result;
        while(!stack.empty()){
            result.push_back(stack.top());
            stack.pop();
        }
        reverse(result.begin(),result.end());
        return result;
    }
};

补充:

reverse(s.begin(),s.end())是C++库函数

今日总结

涉及左右,相邻匹配的问题,使用栈

posted @ 2024-06-17 18:32  跳圈  阅读(21)  评论(0)    收藏  举报