DAY10 - 232.用栈实现队列, 225. 用队列实现栈, 20. 有效的括号, 1047. 删除字符串中的所有相邻重复项

由于栈(队列)底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能),所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)

C++ STL stack

  • push():将元素压入栈顶。
  • pop():将栈顶元素弹出。
  • top():访问栈顶元素。
  • empty():检查栈是否为空。
  • size():返回栈中元素的数量。

C++ STL queue

  • push():将元素加入队列的尾部。
  • pop():将队列的头部元素移除。
  • front():访问队列头部元素。
  • back():访问队列尾部元素。
  • empty():检查队列是否为空。
  • size():返回队列中元素的数量。

232.用栈实现队列

知道两个栈尾尾相接就可以实现队列了,但实现起来还是卡了一下。

class MyQueue {
public:
    stack<int> fronts;
    stack<int> tails;

    MyQueue() {
        
    }
    
    void push(int x) {
        tails.push(x);
    }
    
    int pop() {
        if(fronts.empty()){ //注意这里是fronts为空才可以操作,否则顺序就乱了
            while(!tails.empty()){
                fronts.push(tails.top());
                tails.pop();
            }
        }
        int res=fronts.top();
        fronts.pop();
        return res;
    }
    
    int peek() {
        if(fronts.empty()){
            while(!tails.empty()){
                fronts.push(tails.top());
                tails.pop();
            }
        }
        return fronts.top();
    }
    
    bool empty() {
        return fronts.empty()&&tails.empty();
    }
};

225. 用队列实现栈

队列FIFO,所以即使出队列再入队列顺序也不会改变。而两个栈先弹出再放入顺序就会反转。

class MyStack {
public:
    queue<int> que;

    MyStack() {

    }

    void push(int x) {
        que.push(x);
    }

    int pop() {
        int size = que.size();
        size--;
        while (size--) {
            que.push(que.front());
            que.pop();
        }
        int result = que.front();
        que.pop();
        return result;
    }

    int top(){
        int size = que.size();
        size--;
        while (size--){
            que.push(que.front());
            que.pop();
        }
        int result = que.front(); 
        que.push(que.front());  
        que.pop();
        return result;
    }

    bool empty() {
        return que.empty();
    }
};

20. 有效的括号

一开始面试写了这个题,用的vector没有用stack,换成stack来写一遍

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        int len=s.size();
        for(char c:s){
            if(c=='('||c=='['||c=='{'){
                st.push(c);
            }else if(c==')'){
                if(!st.empty()&&st.top()=='(') st.pop();
                else return false;
            }else if(c==']'){
                if(!st.empty()&&st.top()=='[') st.pop();
                else return false;
            }else if(c=='}'){
                if(!st.empty()&&st.top()=='{') st.pop();
                else return false;
            }
        }
        if(!st.empty()) return false;
        
        return true;
    }
};

但是这样写if else太多了,很不美观,看下标准答案:

class Solution {
public:
    bool isValid(string s) {
        if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
        stack<char> st;
        for (char c:s) {
            if (c == '(') st.push(')');
            else if (c == '{') st.push('}');
            else if (c == '[') st.push(']'); //让左括号入栈
            //如果在过程中st空了则也是错误
            else if (st.empty() || st.top() != c) return false;
            else st.pop();
        }
        return st.empty();
    }
};

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

和括号匹配一样,不过是将栈中剩余的内容再输出而已。还要注意的一个小点是由于栈是FIFO,所以最后res字符串要reverse一下。

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> st;
        for(char c:s){
            if(!st.empty()&&c==st.top()) st.pop();
            else st.push(c);
        }
        string res="";
        while(!st.empty()){
            res+=st.top();
            st.pop();
        }
        reverse(res.begin(),res.end());
        return res;
    }
};
posted @ 2025-03-25 13:22  ChloeChen0221  阅读(11)  评论(0)    收藏  举报