当前位置: 首页 > news >正文

LeetCode 394. 字符串解码(Decode String)

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码讲解
    • 示例测试及结果
      • 输出结果:
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在实际开发中,我们经常需要解析字符串,比如处理模板语言(像 HTML、Markdown、或自定义语法)、实现配置文件解析、甚至在前后端数据传输中做字符串编码与解码。而这道 LeetCode 394《字符串解码》正是一个非常典型的“栈结构解析”题。

它不仅考察我们对字符串处理的熟悉程度,还能锻炼我们对嵌套结构的思维建模能力。很多开发者在刚接触时容易被多层嵌套搞晕,其实只要理解核心思想——用栈保存当前状态,一切就变得简单多了。

描述

题目要求我们把一个经过编码的字符串还原成原始字符串。

编码规则是这样的:

k[encoded_string]

其中 encoded_string 要重复 k 次。例如:

  • "3[a]""aaa"
  • "2[bc]""bcbc"

当然,这题的难点不是这里,而是嵌套结构
比如:

  • "3[a2[c]]" → 里面的 "2[c]" 要先被解出来成 "cc",再重复 3 次得到 "accaccacc"

换句话说,你需要一层层解析 [] 内的内容,直到没有嵌套为止。

题目还保证输入是合法的,没有奇怪的格式,比如不会出现 "3a""2[4]" 这种不合规范的情况。

题解答案

思路其实很直观,只要你能想到“栈”这个数据结构。

我们可以用两个栈:

  • 一个栈 numStack 存放数字(也就是重复次数 k)
  • 一个栈 strStack 存放当前字符串状态

当我们遇到 '[',就把当前的数字和字符串状态压入栈中;
当遇到 ']',就弹出上一个状态,拼接出完整的字符串;
当遇到普通字母时,直接追加到当前字符串。

这个过程其实就像递归一样,只不过我们用栈来模拟递归的过程。

题解代码分析

来看完整的 Swift 实现

import Foundationclass Solution {func decodeString(_ s: String) -> String {var numStack: [Int] = []        // 保存重复次数var strStack: [String] = []     // 保存上一次的字符串状态var currentNum = 0              // 当前的数字var currentStr = ""             // 当前构造的字符串for char in s {if char.isNumber {// 如果是数字,更新当前数字(可能是多位数)currentNum = currentNum * 10 + Int(String(char))!} else if char == "[" {// 遇到左括号,把当前状态压栈numStack.append(currentNum)strStack.append(currentStr)currentNum = 0currentStr = ""} else if char == "]" {// 遇到右括号,弹出栈顶数据let repeatCount = numStack.removeLast()let lastStr = strStack.removeLast()// 把当前字符串重复指定次数后接到上一个状态后面currentStr = lastStr + String(repeating: currentStr, count: repeatCount)} else {// 普通字符,直接拼接currentStr.append(char)}}return currentStr}
}

代码讲解

我们来细拆一下逻辑:

  1. 识别数字
    当遍历到一个数字(比如 "3")时,我们用 currentNum = currentNum * 10 + ... 的方式构建完整数字,这样就能支持多位数(如 "12[a]" → 重复 12 次)。

  2. 遇到 [
    当前字符串和数字状态都要“入栈保存”,因为后面会进入一个新的嵌套层级。
    然后重置 currentStrcurrentNum,为下一层准备。

  3. 遇到 ]
    表示当前嵌套层结束。
    从栈中取出上一个状态,把当前层的结果重复指定次数后拼接上去。

  4. 普通字母
    直接追加在当前字符串 currentStr 里。

这整个流程其实就像在不断地“进入括号、退出括号”,每次退出括号就拼接一次完整字符串。
用栈保存上下文状态,正好能完美处理这种嵌套关系。

示例测试及结果

我们来跑几个典型示例:

let solution = Solution()print(solution.decodeString("3[a]2[bc]"))      // 输出: aaabcbc
print(solution.decodeString("3[a2[c]]"))       // 输出: accaccacc
print(solution.decodeString("2[abc]3[cd]ef"))  // 输出: abcabccdcdcdef
print(solution.decodeString("abc3[cd]xyz"))    // 输出: abccdcdcdxyz

输出结果:

aaabcbc
accaccacc
abcabccdcdcdef
abccdcdcdxyz

是不是很直观?
无论嵌套多少层,只要括号匹配正确,栈的结构都能帮我们把层级理得清清楚楚。

时间复杂度

这段代码整体是 O(n),其中 n 是字符串长度。
每个字符都只被遍历一次,而且入栈、出栈的操作都是 O(1)。

即使有嵌套,也只是逻辑层次不同,时间复杂度依然是线性的。

空间复杂度

空间复杂度取决于栈的深度。
在最坏情况下,比如 "3[2[2[a]]]",栈的深度等于括号嵌套层数。

所以空间复杂度是 O(n),但一般远小于 n,因为嵌套层级通常不会太深。

总结

这道题最大的价值在于它能帮你真正理解“用栈解决嵌套结构”的思想。
它不仅能应用在算法题上,也能帮助你在项目中处理类似的语法结构,比如:

  • 解析配置语言(YAML、JSON、DSL)
  • 模板引擎展开(如 {{#each}} ... {{/each}}
  • 富文本编辑器的格式匹配(HTML 标签闭合检测)

如果你能熟练掌握这种“栈 + 状态保存 + 拼接回溯”的思路,那么很多复杂的字符串题都会迎刃而解。

http://www.dtcms.com/a/465212.html

相关文章:

  • Spring Bean耗时分析工具
  • 济南可信网站网站开发命名规范
  • 应用案例丨3D工业相机如何实现「焊接全工序守护」
  • 网站接广告网站可以叫做系统吗
  • 应用层协议之Telnet协议
  • 科技赋能成长,小康AI家庭医生守护童真
  • 芯谷科技--D7005高效高压降压型DC-DC转换器
  • 玻尿酸:从天然分子到科技美学的全面解析
  • # 3.1.8<3.2.0<3.3.1,Apache DolphinScheduler集群升级避坑指南
  • 微算法科技(NASDAQ:MLGO)基于任务迁移的弹性框架重塑动态扩缩容,赋能边缘智能计算
  • 卡盟网站怎么做图片wordpress换网址插件
  • 【汽车篇】基于深度学习的门盖自动装配系统:汽车制造装配的革新力量
  • 乐迪信息:基于AI算法的煤矿作业人员安全规范智能监测与预警系统
  • 英文电商网站建设泛微oa办公系统教程
  • Windows环境搭建:PostGreSQL+PostGIS安装教程
  • SQL COUNT() 函数详解
  • 中山网站设计收费标准wordpress 右边栏
  • 坦桑尼亚网站域名后缀一个虚拟主机可以放几个网站
  • 从大模型到轻量级部署:知识蒸馏优化技术
  • 速通ACM省铜第二十一天(补) 赋源码(共现的数)
  • 自用,正点Linux虚拟机系统文件概况
  • 从“用框架”到“控系统”——业务模型和技术模型之间的映射
  • 洛谷 / 一本通 - dp 题目详解 7(超详细版)
  • 正点原子RK3568学习日记-GIT
  • 在Minio以STS方式获得临时凭据
  • 【多线程】屏障(Barrier)
  • 通过高新区网站建设兰州市城乡建设局网官网站
  • 商城网站建设如何建设网站设计的公司
  • 【OPENGL ES 3.0 学习笔记】第一天:认识渲染管道
  • 从数据沼泽到智能决策:数据驱动与 AI 融合的中台建设方法论与技术实践指南(二)