栈和队列

栈的应用

  1. 逆序输出:输出次序与处理过程颠倒;递归的深度和输出长度不易预知。如:进制转换。
  2. 延迟缓冲:线性扫描算法模式中,在预读足够长后,方能确定可处理的前缀。如:括号匹配。
  3. 递归嵌套:具有自相似性的问题可递归描述,但分支位置和嵌套深度不固定。如:栈混洗。
  4. 栈式计算:基于栈结构的特定计算模式。如:RPN。

LeetCode504. 七进制数

class Solution {
     
public:
    char digit[7] = {
     '0', '1', '2', '3', '4', '5', '6'};

    string convertToBase7(int num) {
     
        bool is_minus = num < 0;
        num = abs(num);
        if(num == 0) return "0";
        stack<char> stk;
        string ans;
        while(num) stk.push(digit[num % 7]), num /= 7;
        while(stk.size()) ans += stk.top(), stk.pop();
        if(is_minus) ans = '-' + ans;
        return ans;
    }
};

LeetCode946. 验证栈序列
栈混洗问题,模拟一遍过程即可

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

面试题 08.09. 括号
本质上也是栈混洗问题,所有合法的括号组合的数量和栈混洗的数量相同。都是(2*n) ! / (n+1)!/n!。此题可用dfs生成所有序列·,利用一个括号序列合法的充要条件是其前缀和大于等于0。

class Solution {
     
public:
    vector<string> ans;
    string path;
    int n;

    void dfs(int u, int sum){
     
        if(u == n){
     
            if(sum == 0) ans.push_back(path);
            return ;
        }
        if(sum < 0 || sum > n - u) return ;
        path.push_back('(');
        dfs(u+1, sum+1);
        path.pop_back();
        path.push_back(')');
        dfs(u+1, sum-1);
        path.pop_back();
    }

    vector<string> generateParenthesis(int _n) {
     
        n = 2 * _n;
        dfs(0, 0);
        return ans;
    }
};

LeetCode150. 逆波兰表达式求值

class Solution {
     
public:
    bool is_op(string& s){
     
        if(s == "+" || s == "-" || s == "*" || s == "/")
            return true;
        else return false;
    }

    int cal(int num2, string& s, int num1){
     
        if(s == "+") return num2 + num1;
        else if(s == "-") return num2 - num1;
        else if(s == "*") return num2 * num1;
        else return num2 / num1;
    }

    int evalRPN(vector<string>& tokens) {
     
        stack<int> stk;
        for(auto &t: tokens){
     
            if(is_op(t)) {
     
                int num1 = stk.top(); stk.pop();
                int num2 = stk.top(); stk.pop();
                stk.push(cal(num2, t, num1));
            }
            else stk.push(stoi(t));
        }
        return stk.top();
    }
};

栈和队列的相互转换

LeetCode232. 用栈实现队列
两个栈实现队列,stk1用作输入,stk2用作弹出。

class MyQueue {
     
public:
    /** Initialize your data structure here. */
    stack<int> stk1, stk2;

    MyQueue() {
     

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
     
        stk1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
     
        if(stk2.empty()){
     
            while(stk1.size()){
     
                stk2.push(stk1.top()); stk1.pop();
            }
        }
        int t = stk2.top();
        stk2.pop();
        return t;
    }
    
    /** Get the front element. */
    int peek() {
     
        if(stk2.empty()){
     
            while(stk1.size()){
     
                stk2.push(stk1.top()); stk1.pop();
            }
        }
        return stk2.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
     
        return stk1.empty() && stk2.empty();
    }
};

/**
 * 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();
 */

LeetCode225. 用队列实现栈
两个队列实现栈,假设队列只能访问队头。

class MyStack {
     
public:
    /** Initialize your data structure here. */
    queue<int> q1, q2;
    MyStack() {
     

    }
    
    /** Push element x onto stack. */
    void push(int x) {
     
        q1.push(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
     
        while(q1.size() > 1){
     
            q2.push(q1.front());
            q1.pop();
        }
        int res = q1.front(); q1.pop();
        while(q2.size()){
     
            q1.push(q2.front());
            q2.pop();
        }
        return res;
    }
    
    /** Get the top element. */
    int top() {
     
        while(q1.size() > 1){
     
            q2.push(q1.front());
            q1.pop();
        }
        int res = q1.front(); q1.pop();
        while(q2.size()){
     
            q1.push(q2.front());
            q2.pop();
        }
        q1.push(res);
        return res;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
     
        return q1.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();
 */

你可能感兴趣的:(队列,算法,数据结构,dfs,栈)