LeetCode Day14 栈与队列

232 用栈实现队列

题目理解

用两个栈实现队列的功能,支持队列的所有操作。
栈只能使用基本操作。

思路

队列是先进先出,栈是后进先出。怎样用栈实现先进先出的功能呢,用两个栈,一个入,一个出。
当执行队列的push操作时,入栈push;执行队列的pop操作时,需要把栈中最先进入的元素pop出,因此需要将入栈依次pop(),然后push到出栈中,直到入栈为空,此时栈中最先进入的元素就是出栈的top()元素。
查询队首元素,与队列的pop()操作类似,因此,可以在pop()的基础上,读出队首元素,再把pop出来的队首元素push进去即可。
判断队列是否为空,只需要出栈和入栈都为空,则队列为空。

代码

class MyQueue {
public:
    stack<int> In;
    stack<int> Out;
    /** Initialize your data structure here. */
    MyQueue() {

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        In.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        if(Out.empty())
        {
            while(!In.empty()) {
                Out.push(In.top());
                In.pop();
            }
        }
        int res = Out.top();
        Out.pop();
        return res;
    }
    
    /** Get the front element. */
    int peek() {
        int res = this->pop();
        Out.push(res);
        return res;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        if(Out.empty() && In.empty())
            return true;
        return false;
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

225 用队列实现栈

题目理解

用两个队列实现栈的基本功能,队列只能使用基本操作(push、pop、size、empty)

思路

不同于用栈实现队列,队列是先进先出,栈是后进先出,怎样让栈中后进的元素先出来呢,我们需要把栈中先进去的元素存起来,这样才能让后进去的元素先出来,因此使用两个队列,一个队列存另一个队列最后进来的元素之前的元素。
push操作,只需要往队列push即可。
pop操作,则需另一个队列把当前队列的前size-1个元素存起来,然后pop当前队列的元素,最后再把另一个队列存储的元素移回到原队列。
top操作,与pop操作类似,只需把pop出的栈顶元素在push进去即可。
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() {
        while(que1.size() != 1) {
            que2.push(que1.front());
            que1.pop();
        }
        int res = que1.front();
        que1.pop();
        while(que2.size()) {
            que1.push(que2.front());
            que2.pop();
        }
        return res;
    }
    
    /** Get the top element. */
    int top() {
        int res = this->pop();
        que1.push(res);
        return res;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return que1.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

20 有效的括号

题目理解

字符串只由() {} []组成,判断字符串中的括号是否匹配。

思路

对称匹配类的题目,适合使用栈来解决。可以遍历字符串,当遇到’(’ ‘{’ ‘[‘时,向栈中压入对应的’)’ ‘}’ ‘]’,然后在遇到’)’ ‘}’ ‘]’,判断栈顶元素是否和当前元素相等,相等则pop,不相等则显然不匹配。

代码

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        if(s.size() == 1) return false;
        for(auto c : s) {
            if(c == '(')
                st.push(')');
            else if(c == '{')
                st.push('}');
            else if(c == '[')
                st.push(']');
            else if(st.empty() || st.top() != c) //栈为空或者栈顶元素不等于当前字符说明不匹配
                return false;
            else st.pop();
        }
        if(st.empty()) //遍历完后如果栈不为空说明不匹配
            return true;
        return false;
    }
};

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

题目理解

如果字符串相邻元素相等,则删除相等元素,如果删除以后导致目前相邻的元素相等,则目前的重复元素也要删除。

思路

和栈的操作非常相似,如果当前元素和栈顶元素相等,则弹出栈顶元素,再比较,相等则再弹出。最后栈中剩下的元素即为不重复的元素,又因为栈是后进先出,因此最后要反转字符串得到结果。

代码

class Solution {
public:
    string removeDuplicates(string S) {
        stack<char> st;
        string res;
        for(auto c : S) {
            if (st.empty() || c != st.top())
                st.push(c);
            else {
                st.pop();
            }
        }
        while(!st.empty()) {
            res += st.top();
            st.pop();
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

150 逆波兰表达式求值

题目理解

根据逆波兰表示法,求表达式的值。
如"2",“1”,"+",“3”,"*",结果为((2 + 1) * 3) = 9。
逆波兰表示法就是将运算符前两个数字进行相应操作。

思路

使用栈即可解决,将数字压入栈,当遇到运算符时,取出栈顶两个元素进行运算,将运算结果压入栈,以此往复,直到遍历完数组。运算结果即为最后的栈顶元素。

代码

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(auto c : tokens) {
            if(st.empty() || (c != "+" && c != "-" && c != "*" && c != "/"))
                st.push(stoi(c));
            else {
                int num1 = st.top();
                st.pop();
                int num2 = st.top();
                st.pop();
                if(c == "+")
                    st.push(num1 + num2);
                else if(c == "-")
                    st.push(num2 - num1);
                else if(c == "*")
                    st.push(num1 * num2);
                else st.push(num2 / num1);
            }
        }
        return st.top();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值