从零开始刷算法-栈-字符串解码

题目描述

给定一个经过编码的字符串,返回它解码后的结果。编码规则是:
k[encoded_string],表示 encoded_string 在方括号内的部分正好重复 k 次。

例如:

复制代码
输入: s = "3[a2[c]]"
输出: "accaccacc"

思路分析

整道题的关键在于:

遇到 **]**就说明要"展开"最近的一段编码。

而要展开一段编码,必须知道两部分内容:

  1. 括号里的字符串(例如 abc

  2. 前面的数字(例如 3

由于字符串中可能有嵌套(例如 3[a2[c]]),普通的线性扫描难以处理"内层先展开"的逻辑。

因此我们使用 栈(stack) 来模拟整个过程。

栈的思路拆解

  1. 遍历字符串:

    • 如果当前字符不是 ],直接压栈;

    • 如果遇到 ],说明我们找到了一段完整的结构,需要出栈处理。

  2. 当遇到 **]**时:

    • 从栈顶依次弹出字符,直到遇到 '['

    • 这部分拼出的字符串就是当前要重复的内容。

  3. 取出数字部分:

    • '[' 前面紧挨着的可能是一串数字(比如 10[ab]);

    • 从栈顶继续弹出所有数字并拼接;

    • 将其转为整数 k

  4. 重复并压回:

    • 把刚刚取出的字符串重复 k 次;

    • 再把展开结果一个字符一个字符地压回栈中。

  5. 最后:

    • 栈中剩下的就是完全展开的结果,从底到顶拼起来即可。

代码实现

复制代码
class Solution {
public:
    string decodeString(string s) {
        stack<char> st;
        for (char c : s) {
            if (c != ']') {
                // 左括号或普通字符都压栈
                st.push(c);
            } else {
                // 1️⃣ 取出当前方括号内的内容
                string cur;
                while (!st.empty() && st.top() != '[') {
                    cur = st.top() + cur;
                    st.pop();
                }
                st.pop(); // 弹出 '['

                // 2️⃣ 取出重复次数
                string num;
                while (!st.empty() && isdigit(st.top())) {
                    num = st.top() + num;
                    st.pop();
                }
                int k = stoi(num);

                // 3️⃣ 构造展开字符串
                string repeated;
                for (int i = 0; i < k; i++) repeated += cur;

                // 4️⃣ 压回栈中
                for (char ch : repeated) st.push(ch);
            }
        }

        // 5️⃣ 拼接最终结果
        string ans;
        while (!st.empty()) {
            ans = st.top() + ans;
            st.pop();
        }
        return ans;
    }
};

示例演示:3[a2[c]]

步骤 栈内容 说明
读到 '3' 3 压栈
读到 '[' 3 [ 压栈
读到 'a' 3 [ a 压栈
读到 '2' 3 [ a 2 压栈
读到 '[' 3 [ a 2 [ 压栈
读到 'c' 3 [ a 2 [ c 压栈
读到 ']' 3 [ a cc 展开内层得到 "cc"
继续 ']' accaccacc 展开外层得到 "accaccacc"

时间复杂度分析

  • 每个字符最多进栈出栈一次,因此时间复杂度为 O(n)

  • 空间复杂度为 O(n)(使用了辅助栈)。

总结

这题的精髓在于:

用栈"模拟"了递归调用展开的过程。

你可以记住一个通用模板:

"括号匹配 + 层级展开"类问题(如算式计算、字符串解码)几乎都可以用栈解决。

相关推荐
摇滚侠6 分钟前
2025最新 SpringCloud 教程,Nacos-总结,笔记19
java·笔记·spring cloud
在逃热干面10 分钟前
(笔记)获取终端输出保存到文件
java·笔记·spring
爱笑的眼睛1111 分钟前
深入理解MongoDB PyMongo API:从基础到高级实战
java·人工智能·python·ai
笃行客从不躺平20 分钟前
遇到大SQL怎么处理
java·开发语言·数据库·sql
郝学胜-神的一滴21 分钟前
Python中常见的内置类型
开发语言·python·程序人生·个人开发
q***876028 分钟前
Spring Boot 整合 Keycloak
java·spring boot·后端
Billow_lamb29 分钟前
Spring Boot2.x.x全局拦截器
java·spring boot·后端
上不如老下不如小39 分钟前
2025年第七届全国高校计算机能力挑战赛初赛 Java组 编程题汇总
java·计算机能力挑战赛
g***B73844 分钟前
Kotlin协程在Android中的使用
android·开发语言·kotlin
火白学安全1 小时前
《Python红队攻防零基础脚本编写:进阶篇(一)》
开发语言·python·安全·web安全·网络安全·系统安全