【专题十二】栈

📝前言说明:

  • 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础python入门基础C++学习笔记Linux
🎀CSDN主页 愚润泽

你可以点击下方链接,进行该专题内不同子专题的学习

点击链接开始学习
双指针(1)双指针(2)
双指针(3)双指针(4)
滑动窗口(1)滑动窗口(2)
滑动窗口(3)滑动窗口(4)
二分查找(1)二分查找(2)
前缀和(1)前缀和(2)
前缀和(3)位运算(1)
位运算(2)模拟算法
快速排序归并排序
链表哈希表
字符串
队列 + 宽搜优先级队列
BFS 解决 FloodFillBFS 解决最短路径
多源 BFSBFS 解决拓扑排序

题单汇总链接:点击 → 题单汇总(暂时未整理,因为还没刷完)


1047. 删除字符串中的所有相邻重复项

题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/
在这里插入图片描述

个人解

屎山代码:

class Solution {
public:
    string removeDuplicates(string s) {
        string ans;
        for(auto c:s)
        {
            if(ans.empty() || c != ans.back())
                ans.push_back(c);
            else
                ans.pop_back();
        }
        return ans;
    }
};

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)


844. 比较含退格的字符串

题目链接:https://leetcode.cn/problems/backspace-string-compare/description/
在这里插入图片描述

个人解

用时:3:00
屎山代码:

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        string a = "", b = "";
        for(auto c: s)
        {
            if(c == '#' && !a.empty())
                a.pop_back();
            else if(c != '#')
                a.push_back(c);
        }
        for(auto c: t)
        {
            if(c == '#' && !b.empty())
                b.pop_back();
            else if(c != '#')
                b.push_back(c);
        }
        return a == b;
    }
};

时间复杂度: O ( m + n ) O(m + n) O(m+n)
空间复杂度: O ( m + n ) O(m + n) O(m+n)


227. 基本计算器 II

题目链接:https://leetcode.cn/problems/basic-calculator-ii/description/
在这里插入图片描述


优质解

思路:

  • 我们把整个式子看成是:所有数运算后结果的相加(这个结果可能是数本身,可能是和-绑定,可能是*/运算表达式的返回值…)
  • 当⼀个数前⾯是 ’ + ’ 或 ’ - '号的时候,这⼀个数是否会被⽴即计算是「不确定」的,因此我们可以先压⼊栈中。(负数压相反数,相当于-在这个数上运算过了)
  • 当⼀个数前面是 ’ * ’ 或 ’ / '号的时候,这⼀个数可以立即与前⾯的⼀个数进行运算。

代码:

class Solution {
public:
    int calculate(string s) 
    {
        vector<int> st;
        int n = s.size(), i = 0;
        char op = '+';
        while(i < n)
        {
            if(s[i] == ' ') i++;
            else if(s[i] >= '0' && s[i] <= '9')
            {
                // 获得当前数(有可能是多位数)
                int tmp = 0;
                while(i < n && s[i] >= '0' && s[i] <= '9') 
                    tmp = tmp * 10 + (s[i++] - '0');
                if(op == '+') st.push_back(tmp);
                else if(op == '-') st.push_back(-tmp);
                else if(op == '*') st.back() *= tmp;
                else st.back() /= tmp; // back()返回的是引用
            }
            else
            {
                op = s[i];
                i++;
            }
        }
        int ret = 0;
        for(auto x : st) ret += x;
        return ret;
    }
};

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)


394. 字符串解码

题目链接:https://leetcode.cn/problems/decode-string/description/
在这里插入图片描述


优质解

思路:

  • 当我们遇到一个数字时,我们无法直接复制后面的字符串(因为后面的字符串可能还有括号,可能后面的字符还要复制)
  • 所以我们只能把这个“复制信息”存起来 → 这种先进后出的特点就会用到
    在这里插入图片描述

代码:

class Solution {
public:
    string decodeString(string s) 
    {
        stack<string> s_st;
        stack<int> num_st;
        s_st.push(""); // 先加入一个空串处理边界情况
        int i = 0, n = s.size();
        while(i < n)
        {
            if(s[i] <= '9' && s[i] >= '0')
            {
                // 提取数字
                int tmp = 0;
                while(i < n && s[i] <= '9' && s[i] >= '0')
                    tmp = tmp * 10 + (s[i++] - '0');
                num_st.push(tmp);
            }
            else if(s[i] == '[')
            {
                i++;
                string tmp = "";
                while(i < n && s[i] >= 'a' && s[i] <= 'z')
                    tmp += s[i++];
                s_st.push(tmp);
            }
            else if(s[i] == ']')
            {
                int num = num_st.top();
                num_st.pop();
                string tmp = s_st.top();
                s_st.pop();
                for(int j = 0; j < num; j++)
                    s_st.top() += tmp;
                i++;
            }
            else
            {
                string tmp = "";
                while(i < n && s[i] >= 'a' && s[i] <= 'z')
                    tmp += s[i++];
                s_st.top() += tmp;
            }
        }
        return s_st.top();
    }
};

时间复杂度: O ( n ∗ a v g ) O (n * avg) O(navg), n 是输入字符串的长度,avg 是平均重复次数
空间复杂度: O ( m + l ) O (m + l) O(m+l), m 是嵌套括号的最大深度,l 是输出字符串的最大长度


946. 验证栈序列

题目链接:https://leetcode.cn/problems/validate-stack-sequences/description/
在这里插入图片描述

个人解

屎山代码:

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> st;
        int n = pushed.size(), i = 0, j = 0;
        while(i < n)
        {
            st.push(pushed[i++]);
            while(!st.empty() && st.top() == popped[j]) // 判断栈顶元素是否能出栈
            {
                st.pop();
                j++;
            }
        }
        return st.empty();
    }
};

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚润泽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值