算法刷题day09|栈与队列:232. 用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项

 栈和队列的基本操作

栈stack

数据存取:

数据存取:

  • push(elem); //向栈顶添加元素

  • pop(); //从栈顶移除第一个元素

  • top(); //返回栈顶元素

大小操作:

  • empty(); //判断堆栈是否为空

  • size(); //返回栈的大小

队列queue

数据存取:

  • push(elem); //往队尾添加元素

  • pop(); //从队头移除第一个元素

  • back(); //返回最后一个元素

  • front(); //返回第一个元素

大小操作:

  • empty(); //判断堆栈是否为空

  • size(); //返回栈的大小

双端队列deque 

大小操作:

  • deque.empty(); //判断容器是否为空

  • deque.size(); //返回容器中元素的个数

  • deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

  • deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

两端插入操作:

  • push_back(elem); //在容器尾部添加一个数据

  • push_front(elem); //在容器头部插入一个数据

  • pop_back(); //删除容器最后一个数据

  • pop_front(); //删除容器第一个数据

指定位置操作:

  • insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。

  • insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。

  • insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。

  • clear(); //清空容器的所有数据

  • erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。

  • erase(pos); //删除pos位置的数据,返回下一个数据的位置。

数据存取: 

  • front(); //返回容器中第一个数据元素

  • back(); //返回容器中最后一个数据元素

232. 用栈实现队列

class MyQueue {
public:
    stack<int> s1;
    stack<int> s2;
    MyQueue() {

    }
    
    void push(int x) {
        s1.push(x);
    }
    
    int pop() {
        if (s2.empty()){
            while (!s1.empty()){
                s2.push(s1.top());
                s1.pop();
            }
        }
        int result = s2.top();
        s2.pop();
        return result;
    }
    
    int peek() {
        if (s2.empty()){
            while(!s1.empty()){
                s2.push(s1.top());
                s1.pop();
            }
        }
        return s2.top();
    }
    
    bool empty() {
       if (s1.empty() && s2.empty()){
        return true;
       } else {
        return false;
       }
    }
};

225. 用队列实现栈

deque写法

当时没想出来单个queue的写法,就走了捷径,deque本身就可以当做一个stack使用

class MyStack {
public:
    deque<int> stk;
    MyStack() {

    }
    
    void push(int x) {
        stk.push_back(x);
    }
    
    int pop() {
        int result = stk.back();
        stk.pop_back();
        return result;
    }
    
    int top() {
        return stk.back();
    }
    
    bool empty() {
        return stk.empty();
    }
};

单queue写法 

pop:将queue的前size - 1个(不包含queue的末尾元素)插入到queue末尾,然后将对头元素pop(也就是原始queue 的末尾元素)

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() {
        return que.back();
    }
    
    bool empty() {
        return que.empty();
    }
};

20. 有效的括号

简单易懂版 

遇到左括号就进栈,如果遇到右括号,则判断是否有左括号进行匹配(此时要判断栈是否为空,如果为空则说明有多余的括号,直接return false),若匹配则pop栈顶元素,否则return false。最后如果栈空则正确。

 

class Solution {
public:
    bool isValid(string s) {
        stack<char> t;
        int len=s.size();
        if(len % 2 != 0) return false;
        for(int i = 0; i < len; i++){
            if(s[i]=='('||s[i]=='['||s[i]=='{'){
                t.push(s[i]);
            }else{
                switch(s[i]){
                    case ']':
                        if(!t.empty() &&t.top()=='[') t.pop();
                        else return false;
                        break;
                    case '}':         
                        if(!t.empty() &&t.top()=='{') t.pop();
                        else return false;
                        break;
                    case ')':     
                        if(!t.empty() &&t.top()=='(') t.pop();
                        else return false;
                        break;
                }
            }
        }
        if(t.empty())return true;
        else return false;
    }
};

map集合+栈

定义一个map集合pairs和栈stk,集合里面存放括号对,key为右括号,value为左括号,遍历字符串,遇到左括号直接进栈(只有左括号进栈,右括号仅限于匹配),如果遇到右括号,则判断栈顶是否为匹配的左括号,若是则pop,否则false,最后如果栈内没有多余的左括号,则匹配成功。

class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        //若字符串长度为奇数,永远不可能匹配
        if (n % 2 == 1) {
            return false;
        }

        unordered_map<char, char> pairs = {
            {')', '('},
            {']', '['},
            {'}', '{'}
        };
        stack<char> stk;
        for (char ch: s) {
            //遇到右括号,count是匹配的key
            if (pairs.count(ch)) {
                //若栈为空或栈顶元素和value值不匹配,则false
                if (stk.empty() || stk.top() != pairs[ch]) {
                    return false;
                }
                stk.pop();
            }
            else {
                //左括号入栈
                stk.push(ch);
            }
        }
        return stk.empty();
    }
};

 代码随想录版

有三种不匹配的情况,

1.第一种情况,字符串里左方向的括号多余了 ,所以不匹配。

第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

 2.第二种情况,括号没有多余,但是 括号的类型没有匹配上。

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

3.第三种情况,字符串里右方向的括号多余了,所以不匹配。 

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

class Solution {
public:
    bool isValid(string s) {
        if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
        stack<char> st;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '(') st.push(')');
            else if (s[i] == '{') st.push('}');
            else if (s[i] == '[') st.push(']');
            // 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
            // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
            else if (st.empty() || st.top() != s[i]) return false;
            else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
        }
        // 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
        return st.empty();
    }
};

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

定义一个栈stk,如果栈不为空或者当前遍历的字符s[i]与栈顶元素不同,则将字符压入栈顶;否则,栈顶元素出栈。将此时栈中元素再逆序输出就是结果串。

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> stk;
        string result = "";
        for (int i = 0; i < s.size(); i++){
            if (!stk.empty() && s[i] == stk.top()){
                stk.pop();
            }else {
                stk.push(s[i]);
            }
        }
        while (!stk.empty()){
            result += stk.top();
            stk.pop();
        }
        reverse(result.begin(), result.end());
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值