栈算法合集

一. 232. 用栈实现队列🔗

题目要求:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

1. 正常做法

class MyQueue {
public:
    stack<int> out; //输出栈
    stack<int> in;  //输入栈
    MyQueue() {
    
    }
    
    void push(int x) { //将元素 x 推到队列的末尾
        if(out.empty()) {
            out.push(x);
        }
        else
            in.push(x);
    }
    
    int pop() { //从队列的开头移除并返回元素
        
        int temp = out.top();
        out.pop();
            
        
        if(out.empty()) {
            while(!in.empty()){
                out.push(in.top());
                in.pop();
            }
        }
        return temp;
    }
    
    int peek() { //返回队列开头的元素
        return out.top();
    }
    
    bool empty() {
        return (in.empty() && out.empty());
    }
};


二. 20. 有效的括号🔗

题目要求:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

1. 栈做法

class Solution {
public:
    bool isValid(string s) {
        stack<char> temp;
        for(auto e: s){
            if(e=='(' || e=='{' || e=='[')
                temp.push(e);
            else { // if(e==')' || e=='}' || e==']')
                // 在访问栈顶前检查栈是否为空
                if(temp.empty()) //还没遍历完,已经没有左括号匹配了
                    return false; //不是有效的
                if((e==')' && temp.top()=='(') 
                || (e=='}' && temp.top()=='{' )
                || (e==']' && temp.top()=='[' )) {
                    temp.pop();
                } 
                else {
                    return false;
                }
            }
            
        }
        if(temp.empty()) //所有元素被比较完了,符合要求有效
            return true; //避免[()
        return false;
    }
};

2. 哈希表做法

class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        if (n % 2 == 1) {
            return false;
        }

        unordered_map<char, char> pairs = {
            {')', '('},
            {']', '['},
            {'}', '{'}
        };
        stack<char> stk;
        for (char ch: s) {
            if (pairs.count(ch)) {
                if (stk.empty() || stk.top() != pairs[ch]) {
                    return false;
                }
                stk.pop();
            }
            else {
                stk.push(ch);
            }
        }
        return stk.empty();
    }
};

三. 155. 最小栈🔗

题目要求:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

常数时间内检索到最小元素的栈,要求O(1),而不是全部遍历一遍

1. 两个栈

/*
主栈和最小栈,查看最小元素用最小栈,删除主栈的栈顶元素时,也要更新最小栈的栈顶元素
比如入栈-2 0 -3
主栈为[-2, 0, -3]
最小栈为[-2, -2, -3]
*/

class MinStack {
public:
    stack<int> main_stack;
    stack<int> min_stack;
    MinStack() {
        
    }
    
    void push(int val) {
        main_stack.push(val);
        if(min_stack.empty())
            min_stack.push(val);
        else
            min_stack.push(min(val,min_stack.top()));
    }
    
    void pop() {
        min_stack.pop();
        main_stack.pop();
    }
    
    int top() {
        return main_stack.top();
    }
    
    int getMin() {
        return min_stack.top();
    }
};

2. 一个栈

class MinStack {
public:
    stack<pair<int,int>> main_stack;
    
    MinStack() {
        
    }
    
    void push(int val) {
        int _first = val;
        int _second;
        if(main_stack.empty()) 
            _second = val;
        else
            _second = min(val, main_stack.top().second);
        pair<int, int> temp = {_first, _second};
        main_stack.push(temp);
    }
    
    void pop() {
       main_stack.pop();
    }
    
    int top() {
        return main_stack.top().first;
    }
    
    int getMin() {
       return main_stack.top().second;
    }
};

四. 739. 每日温度🔗

题目要求:给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

1. 单调栈

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        
        int n = temperatures.size();
        // 1. 初始化答案数组,全设为 0(兜底策略:如果没人比它热,默认就是 0)
        vector<int> ret(n,0); 
        stack<int> st;// 2. 开辟单调栈,千万记住:里面存的是【索引】!
       
        for(int i=0; i < n; ++i) {
            // 只要栈不为空,且“新人”的温度 > “栈顶”的温度
            while(!st.empty() && temperatures[i] > temperatures[st.top()]) {
                int temp = i - st.top(); // 计算相隔天数,记入答案
                ret[st.top()] = temp;
                st.pop();
            }
            st.push(i);
        }


        return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值