代码随想录 栈与队列p1

栈与队列理论基础

栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。

用栈实现队列

这是一个什么问题

用栈实现队列的 push pop peek(返回队列的首部元素) empty

思路

用两个栈来实现队列,一个输入栈一个输出栈
push就把数放入输入栈中,
pop,两种情况,一种是输出栈为空,这时候就把输入栈中的所有数都压入输出栈中,这样就把顺序调换了,这时候输出栈的第一个数就是模拟队列的首元素,也就是一开始进入模拟队列的值,也是一开始进入输入栈的值。第二种情况是输出栈不为空,这时候就把输出栈的top输出就好了。
peek和pop一样,就是不对栈进行变动,只查看输出栈的首个元素就行
empty是要看两个栈是否都为空

代码

class MyQueue {
public:
    stack<int> stackIn;
    stack<int> stackOut; 
    MyQueue() {

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

用队列来实现栈

思路

一个队列就可以实现栈

push,就直接push就ok

pop 把队列中除去最后一个数之外的所有数按顺序加入队列中,这样顺序就对了

top 和 pop一个思路就是不要弹出去,把最后一个数重新放回队尾

empty就正常判断就好

用result存上结果再pop,利用队列的长度来循环实现pop和top

代码

class MyStack {
public:
    queue<int> q1;
    MyStack() {

    }
    
    void push(int x) {
        q1.push(x);
    }
    
    int pop() {
        int times = q1.size();
        for (int i = 0; i < times - 1; i++) {
            q1.push(q1.front());
            q1.pop();
        }
        int result = q1.front();
        q1.pop();
        return result;
    }
    
    int top() {
        int times = q1.size();
        for (int i = 0; i < times - 1; i++) {
            q1.push(q1.front());
            q1.pop();
        }
        int result = q1.front();
        q1.push(q1.front());
        q1.pop();
        return result;
    }
    
    bool empty() {
        if (q1.empty()) {
            return true;
        }
        return false;
    }
};

有效的括号

这是一个什么问题

看给的一堆括号,是不是能两两按正确的顺序和方向配对的,顺序是左括号在左右括号在右,两个括号的方向也要和正常的括号方向一致。

思路

一个栈,循环字符串里的括号,要是能和栈顶的括号匹配上,那就把栈顶的括号弹出去,要是匹配不上,那就压进去,循环结束后看栈是否为空,如果是空那就是有效的括号。

代码

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

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

和上面的思路一样的

注意一下最后要输出一个字符串,就需要把栈里的数pushback到字符串中,还需要reverse一下字符串

代码

class Solution {
public:

    string removeDuplicates(string s) {
        stack<char> st;
        string result;
        for (int i = 0; i < s.size(); i++) {
            if (st.empty() || st.top() != s[i]) {
                st.push(s[i]);
            }
            else {
                st.pop();
            }
        }
        while(!st.empty()) {
            result.push_back(st.top());
            st.pop();
            }
        reverse(result.begin(), result.end());
        return result;
    }
};

逆波兰表达式

思路

一个栈,不是操作符就压入栈,是操作符的部分再根据操作符的种类去计算,计算结果再亚入栈中要定义两个变量放两个操作数,注意他们的顺序,他们是从栈里取出来的,第二个其实是第一个。还要注意类型是字符还是字符串

代码

class Solution {
public:
    stack<int> st;
    int evalRPN(vector<string>& tokens) {
        for (int i = 0; i < tokens.size(); i++) {
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
                int num2 = st.top();
                st.pop();
                int num1 = st.top();
                st.pop();
                if (tokens[i] == "+") st.push(num1 + num2);
                if (tokens[i] == "-") st.push(num1 - num2);
                if (tokens[i] == "*") st.push(num1 * num2);
                if (tokens[i] == "/") st.push(num1 / num2);
            }
            else {
                st.push(stoi(tokens[i]));
            }
        }
        return st.top();
    }
};

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值