经典栈——从LeetCode题海中总结常见套路

栈总结过一篇:

https://xduwq.blog.csdn.net/article/details/105180380

但是这篇的水题比较多,LeetCode有些栈相关的题非常经典,值得再总结一篇!

主要分成三大类:括号类、栈类设计题、逆波兰类

目录

括号类栈题

栈的常规思路题:LeetCode20.有效的括号

LeetCode1021.删除最外层的括号

LeetCode921.使括号有效的最少添加

栈类设计题

用数组模拟栈:LeetCode1381.设计一个支持增量操作的栈

vector模拟:LeetCode155.最小栈

双栈模拟队列:LeetCode面试题09.用两个栈模拟队列

逆波兰算法及其延伸

逆波兰:Leetcode150.逆波兰表达式求值

逆波兰延伸:LeetCode224.基本计算器


括号类栈题

栈的常规思路题:LeetCode20.有效的括号

如果处理逆波兰算法有些思考的话,这道题其实非常容易有思路!这是栈的常规套路之一!

LeetCode官方的动图,很好理解!

经典栈——从LeetCode题海中总结常见套路_第1张图片

经典栈——从LeetCode题海中总结常见套路_第2张图片

class Solution {
public:
    bool isValid(string s) {
        stack sta;
        for(int i=0;i

LeetCode1021.删除最外层的括号

这题真妙啊,要不是看了评论区,怎么也不会想到可以用栈来求解!

经典栈——从LeetCode题海中总结常见套路_第3张图片

class Solution {
public:
	string removeOuterParentheses(string S) {
		string res = "";
		stack mystack;
		for (int i = 0; i < S.size(); i++) {
			if (S[i] == ')')
				mystack.pop();
			if (!mystack.empty())
				res+=S[i];
			if (S[i] == '(')
				mystack.push('(');
		}
		return res;
	}
};

LeetCode921.使括号有效的最少添加

这题是上面那题的姊妹版,同样用栈stack解决,但是注意先判断栈是否为空!

经典栈——从LeetCode题海中总结常见套路_第4张图片

class Solution {
public:
    int minAddToMakeValid(string S) {
        stack s;
        for(int i=0;i

栈类设计题

这类设计题,出现的也很多,总体来说套路比较固定,闲的时候消遣一下还是挺不错的。

用数组模拟栈:LeetCode1381.设计一个支持增量操作的栈

经典栈——从LeetCode题海中总结常见套路_第5张图片

class CustomStack {
public:
    int maxs;
    vector v;
    CustomStack(int maxSize) {
        maxs = maxSize;
    }
    
    void push(int x) {
        if(v.size()>=maxs)
            return;
        v.push_back(x);
        return;
    }
    
    int pop() {
        if(v.size()<=0)
            return -1;
        v.erase(--v.end());//注意这里的--操作!
        return v[v.size()];
    }
    
    void increment(int k, int val) {
        if(v.size()>=k){
            for(int i=0;ipush(x);
 * int param_2 = obj->pop();
 * obj->increment(k,val);
 */

vector模拟:LeetCode155.最小栈

经典栈——从LeetCode题海中总结常见套路_第6张图片

class MinStack {
public:
    vector v;
    /** initialize your data structure here. */
    MinStack() {
        
    }
    
    void push(int x) {
        v.push_back(x);
    }
    
    void pop() {
        v.erase(--v.end());
    }
    
    int top() {
        return *(--v.end());
    }
    
    int getMin() {
        int min = v[0];
        for(int i=0;ipush(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

同样的还有LeetCode最大栈,可惜我不是VIP还做不了……

双栈模拟队列:LeetCode面试题09.用两个栈模拟队列

经典栈——从LeetCode题海中总结常见套路_第7张图片

直接用vector偷懒方法:

class CQueue {
public:
    vector v;
    CQueue() {

    }
    
    void appendTail(int value) {
        v.push_back(value);
    }
    
    int deleteHead() {
        if(v.size()==0)
            return -1;
        int temp = *(v.begin());
        v.erase(v.begin());
        return temp;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

正经的双栈实现,效率反而下降了不少!

class CQueue {
public:
    stack s;
    int size = 0;
    CQueue() {

    }
    
    void appendTail(int value) {
        s.push(value);
    }
    
    int deleteHead() {
        if(s.size()==0)
            return -1;
        stack temp;
        while(!s.empty()){
            temp.push(s.top());
            s.pop();
        }
        int ans = temp.top();
        temp.pop();
        while(!temp.empty()){
            s.push(temp.top());
            temp.pop();
        }
        return ans;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

逆波兰算法及其延伸

逆波兰:Leetcode150.逆波兰表达式求值

最经典的一道栈的题目,想当年为了弄懂这题可是花了不少劲,现在看来实属easy!

经典栈——从LeetCode题海中总结常见套路_第8张图片

class Solution {
public:
    int evalRPN(vector& tokens) {
        stack st;
        for(int i=0;i

逆波兰延伸:LeetCode224.基本计算器

经典栈——从LeetCode题海中总结常见套路_第9张图片

(后面补)

你可能感兴趣的:(LeetCode经典,算法—STL与数据结构,LeetCode)