面试经典150题 -- 栈(总结)

总的链接

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

面试经典150题 -- 栈(总结)_第1张图片

关于栈 -- stack 的学习链接

c++的STL中的栈 -- stack-CSDN博客

20 . 有效的括号

面试经典150题 -- 栈(总结)_第2张图片

这题直接用栈模拟就好了;

这里用一种取巧的方法 , 当遇见左括号,加入右括号,遇到右括号,直接判断栈顶元素是不是与当前元素相等(这样可以避免再开一个哈希表来存相应括号之间的映射关系),相等的话,pop栈顶,否则,直接return false;

class Solution {
public:
    bool isValid(string s) {
        stack st ;
        for(char 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();
        }
        return st.empty() ;
    }
};

71 . 简化路径

先求出夹在两个/之间的目录名,根据题意,对于空或" . "都不用管,然后用栈模拟,如果不是"..",那么直接入栈,是".."的话,弹出栈顶的字符串;

class Solution {
public:
    vector get(string p,char ch){
        vector ans ;
        string cur ;
         for(char c : p){
             if(c == ch){
                 ans.push_back(cur);
                 cur.clear();
             }else{
                 cur += c ;
             }
         }
         ans.push_back(cur);
         return ans ;
    }
    string simplifyPath(string path) {
        vector p = get(path,'/');
        vector stk ;
        for(string s : p){
            if(s==".."){
                if(!stk.empty())
                    stk.pop_back();
            }else if(!s.empty() && s!="."){
                stk.push_back(s);
            }
        }
        string ans  ;
        if(stk.empty()){
            ans = "/";
        }else{
            for(string s : stk){
                ans += "/" + s ;
            }
        }
        return ans ;
    }
};

155 . 最小栈

用一个栈来模拟正常的操作,用一个递减的栈来维护栈顶为当前序列的最小元素;

详情请看代码 : 

class MinStack {
public:
    stack mi,st;
    MinStack() {
        mi.push(INT_MAX) ;
    }
    
    void push(int val) {
        st.push(val) ;
        mi.push(min(val,mi.top()));
    }
    
    void pop() {
        st.pop();
        mi.pop();
    }
    
    int top() {
        return st.top() ;
    }
    
    int getMin() {
        return mi.top() ;
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

150 . 逆波兰表达式求值

栈的典型例题,如果是运算符,就取出栈顶两位元素进行运算,然后将结果压入栈中,如果是数字,直接压入栈中,最后返回栈顶元素即为运算结果 ;

typedef long long LL ;
class Solution {
public:
    int evalRPN(vector& tokens) {
        stack st ;
        for(string s : tokens){
            if(s=="+" ||s=="-" ||s=="*" ||s=="/"){
                LL x = st.top();
                st.pop() ;
                LL y = st.top();
                st.pop();
                if(s=="+") st.push(x+y);
                else if(s=="-") st.push(y-x);
                else if(s=="*") st.push(1LL * y * x);
                else st.push(y / x);
            }else{
                st.push(stoll(s));
            }
        }
        return st.top() ;
    }
};

224 . 基本计算器

直接用栈模拟 ;

class Solution {
public:
    void replace(string& s){
        int pos = s.find(" ");
        while (pos != -1) {
            s.replace(pos, 1, "");
            pos = s.find(" ");
        }
    }
    int calculate(string s) {
        // 存放所有的数字
        stack nums;
        // 为了防止第一个数为负数,先往 nums 加个 0
        nums.push(0);
        // 将所有的空格去掉
        replace(s);
        // 存放所有的操作,包括 +/-
        stack ops;
        int n = s.size();
        for(int i = 0; i < n; i++) {
            char c = s[i];
            if(c == '(')
                ops.push(c);
            else if(c == ')') {
                // 计算到最近一个左括号为止
                while(!ops.empty()) {
                    char op = ops.top();
                    if(op != '(')
                        calc(nums, ops);
                    else {
                        ops.pop();
                        break;
                    }
                }
            }
            else {
                if(isdigit(c)) {
                    int cur_num = 0;
                    int j = i;
                    // 将从 i 位置开始后面的连续数字整体取出,加入 nums
                    while(j  0 && (s[i - 1] == '(' || s[i - 1] == '+' || s[i - 1] == '-')) {
                        nums.push(0);
                    }
                    // 有一个新操作要入栈时,先把栈内可以算的都算了
                    while(!ops.empty() && ops.top() != '(')
                        calc(nums, ops);
                    ops.push(c);
                }
            }
        }
        while(!ops.empty())
            calc(nums, ops);
        return nums.top();
    }
    void calc(stack &nums, stack &ops) {
        if(nums.size() < 2 || ops.empty())
            return;
        int b = nums.top(); nums.pop();
        int a = nums.top(); nums.pop();
        char op = ops.top(); ops.pop();
        nums.push(op == '+' ? a+b : a-b);
    }
};

你可能感兴趣的:(leetcode,算法学习,面试,leetcoe面试150题,leetcode,c++,算法)