zoukankan      html  css  js  c++  java
  • 算法-栈,队列

    常见的栈与队列算法题

    1.使用队列实现栈

    2.使用栈实现队列

    3.包含最小值函数的栈

    4.合法的出栈序列

    5.简单计算器


    1.队列实现栈

    class MyStack {
    public:
        /** Initialize your data structure here. */
        MyStack() {
            
        }
        
        /** Push element x onto stack. */
        void push(int x) {
            int len=data.size();
            data.push(x);
            while(len>0){
                data.push(data.front());
                data.pop();
                len--;
            }
        }
        
        /** Removes the element on top of the stack and returns that element. */
        int pop() {
            int res=data.front();
            data.pop();
            return res;
            
        }
        
        /** Get the top element. */
        int top() {
            return data.front();
        }
        
        /** Returns whether the stack is empty. */
        bool empty() {
            return data.empty();
        }
    private:
        std::queue<int> data;
    };
    
    /**
     * 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();
     */

    主要是push函数的编写。x进队后,让之前的元素 一 一 出队再入队。


    2.栈实现队列

    class MyQueue {
    public:
        /** Initialize your data structure here. */
        MyQueue() {
            
        }
        
        /** Push element x to the back of queue. */
        void push(int x) {
            while(s.size()){
                s_temp.push(s.top());
                s.pop();
            }
            s.push(x);
            while(s_temp.size()){
                s.push(s_temp.top());
                s_temp.pop();
            }
        }
        
        /** Removes the element from in front of queue and returns that element. */
        int pop() {
            int res=s.top();
            s.pop();
            return res;
        }
        
        /** Get the front element. */
        int peek() {
            return s.top();
        }
        
        /** Returns whether the queue is empty. */
        bool empty() {
            return s.empty();
        }
    private:
        std::stack<int> s,s_temp;
    };
    
    /**
     * 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();
     */

    3.最小值栈

    设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

    • push(x) -- 将元素 x 推入栈中。
    • pop() -- 删除栈顶的元素。
    • top() -- 获取栈顶元素。
    • getMin() -- 检索栈中的最小元素。
    class MinStack {
    public:
        /** initialize your data structure here. */
        MinStack() {
            
        }
        
        void push(int x) {
            s.push(x); 
            if(sMin.empty() || x <= sMin.top()){
                sMin.push(x);
            }
        }
        
        void pop() {
            if(s.top()==sMin.top()){
                s.pop();
                sMin.pop();
            }else{
                s.pop();
            }
        }
        
        int top() {
            return s.top();
        }
        
        int getMin() {
            return sMin.top();
        }
    private:
        std::stack<int> s,sMin;
    };
    
    /**
     * Your MinStack object will be instantiated and called as such:
     * MinStack obj = new MinStack();
     * obj.push(x);
     * obj.pop();
     * int param_3 = obj.top();
     * int param_4 = obj.getMin();
     */

    用另一个栈sMin记录最小值。空间复杂度O(n).


    4.合法的出栈序列

    class Solution {
    public:
        bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
            stack<int> s;
            int len=pushed.size();
            int i=0,j=0;
            while(i<len){
                s.push(pushed[i++]);
                while(!s.empty()){
                    if(s.top()==popped[j]){
                        s.pop();
                        j++;
                    }else{
                        break;
                    }
                }
                
            }
            return s.empty();
        }
    };

    借助一个栈s,模拟进出栈顺序。遍历pushed数组,先将元素进栈。然后再开一个出栈循环,若栈不空,将栈顶与popped数组元素比较,相同则出栈,继续下一个循环;不同则跳出出栈循环,继续外面的进栈操作。最后返回是否栈空。以上应该是最为清晰的思路了,之前我也写过两个,一个暴力法判断,时间复杂度较高,逻辑也很复杂;另一个也是模拟进出栈,但是思路太乱,代码逻辑冗余混乱,简单来说就是模拟的不够真实,反而导致自己思路不畅。


    5.简单计算器

    实现一个基本的计算器来计算一个简单的字符串表达式的值。

    字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -非负整数和空格

    class Solution {
    private:
        stack<int> num;
        stack<char> sign;
        void compute(stack<int> &num, stack<char> &sign) {
            int num2 = num.top(); num.pop();
            int num1 = num.top(); num.pop();
            if (sign.top() == '+') num.push(num1 + num2);
            else if (sign.top() == '-') num.push(num1 - num2);
            sign.pop();
    }
    public:
        int calculate(string s) {
            int len = s.size();
            if (len == 0) return 0;
                int temp = 0;
                for (int i = 0; i < len; i++) {
                if (s[i] == ' ') continue;
                else if (s[i] == '(') {
                    sign.push(s[i]);
                    continue;
                }
                else if (s[i] >= '0' && s[i] <= '9') {
                    temp = s[i] - '0';
                    while (i + 1 != len && s[i + 1] >= '0' && s[i + 1] <= '9') {
                        temp = temp * 10 + s[i+1] - '0';
                        i++;
                    }
                    num.push(temp);
                    temp = 0;
                }
                else if (s[i] == '+' || s[i] == '-') {
                    sign.push(s[i]);
                    continue;
                }
                else if (s[i] == ')') {
                    if (sign.top() != '(') {
                        compute(num, sign);
                    }
                    sign.pop();
                }
    
                if (!sign.empty()&& sign.top() != '(') {
                    compute(num,sign);
                }
            }
            return num.top();
        }        
    };

     括号也入栈,否则即使结果正确也不符合括号规定的顺序,主要是这里只有加减法,也不出错。

  • 相关阅读:
    4、现有的命名方式有多少种?请举例说明。
    第二次作业
    第一次作业
    RateLimiter源码
    使用ASM字节码框架实现动态代理
    Java流机制学习
    Java8 Stream 学习总结
    XML实体解析器的作用
    DefaultResouceLoader的设计
    RSA 非对称加密 数字签名 数字证书
  • 原文地址:https://www.cnblogs.com/chendaniu/p/10235484.html
Copyright © 2011-2022 走看看