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

题目描述

给定一个经过编码的字符串,返回它解码后的结果。编码规则是:
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)(使用了辅助栈)。

总结

这题的精髓在于:

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

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

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

相关推荐
阿里嘎多学长3 小时前
2026-04-30 GitHub 热点项目精选
开发语言·程序员·github·代码托管
abcnull5 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡5 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan5 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054735 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路6 小时前
C++23概述
java·c++·c++23
时空系6 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
专注API从业者7 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
CHANG_THE_WORLD7 小时前
python 批量终止进程exe
开发语言·python