🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。

🚀 力扣热题 394:字符串解码(详细解析)

📌 题目描述

力扣 394. 字符串解码

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为:k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。你可以认为 k 总是一个正数。

注意:输入字符串中只包含数字、英文字母、方括号 [] 和不会嵌套的数字。

🌟 示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"

🌟 示例 2:

输入:s = "3[a2[c]]"
输出:"accaccacc"

🌟 示例 3:

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

💡 解题思路

✅ 栈结构(Stack)解法

这是一个经典的 栈应用题,核心思路是:

  • 遇到 [ :将当前数字(重复次数)和字符串入栈。
  • 遇到 ] :弹出栈顶元素,构造新字符串。
  • 遇到字母:追加到当前字符串中。

我们维护两个栈:

  1. 数字栈:存储重复次数。
  2. 字符串栈:存储括号外的字符串。

💻 Go 实现代码

✅ 方法一:使用两个栈

func decodeString(s string) string {
   
    numStack := []int{
   }
    strStack := []string{
   }
    currStr := ""
    num := 0

    for _, ch := range s {
   
        if ch >= '0' && ch <= '9' {
   
            num = num*10 + int(ch-'0')
        } else if ch == '[' {
   
            numStack = append(numStack, num)
            strStack = append(strStack, currStr)
            num = 0
            currStr = ""
        } else if ch == ']' {
   
            repeat := numStack[len(numStack)-1]
            numStack = numStack[:len(numStack)-1]

            prevStr := strStack[len(strStack)-1]
            strStack = strStack[:len(strStack)-1]

            temp := ""
            for i := 0; i < repeat; i++ {
   
                temp += currStr
            }
            currStr = prevStr + temp
        } else {
   
            currStr += string(ch)
        }
    }
    return currStr
}

✅ 方法二:递归解法

另一种常见的解法是使用递归。递归的思想是将当前字符串按照解码规则拆解,每次遇到 ] 就进行一层解码,然后返回结果。我们通过递归调用来处理字符串中的每一部分。

递归思路:

  • 遇到数字时,开始收集数字,表示重复次数。
  • 遇到 [ 时,递归解析其中的字符串,并将解码后的部分乘以数字。
  • 遇到 ] 时,返回当前的结果并将结果拼接到之前的解码字符串中。

步骤:

  • 遇到字母,直接拼接到当前的解码字符串。
  • 遇到数字,记录并构建重复次数。
  • 遇到 [ 时,开始递归调用处理括号内的字符串。
  • 遇到 ] 时,返回当前解析的结果并继续处理外部字符串。

    ✅ 方法二:递归解法

    ```go
    func decodeString(s string) string {
    index := 0
    return decodeHelper(s, &index)
    }

func decodeHelper(s string, index int) string {
res := ""
for
index < len(s) {
ch := s[index]
if ch >= '0' && ch <= '9' {
num := 0
for
index < len(s) && s[index] >= '0' && s[index] <= '9' {
num = num10 + int(s[index]-'0')
index++
}
index++ // skip '['
str := decodeHelper(s, index)
index++ // skip ']'
for i := 0; i < num; i++ {
res += str
}
} else if ch == ']' {
return res
} else {
res += string(ch)
index++
}
}
return res
}
```

【比较分析】

方法 特点 处理步骤 处理嵌套性 应用场景
栈解法 简洁直观,便于理解 递渐构造字符串 支持嵌套 适合初学者
递归解法 逻辑清晰,方便处理嵌套结构 循环解析,函数循环构造结果 更适合深度嵌套规则 高级结构处理

⏳ 复杂度分析

操作 时间复杂度 空间复杂度
栈/递归 $O(n)$ $O(n)$
  • n 是字符串长度,遍历一遍,各步操作均为常数时间
  • 空间用于栈或递归调用的结果缓存

🌟 总结

  • 栈和递归都是解决本题的有效途径
  • 栈解法更加简单直观,适合初学和面试习题
  • 递归解法适合处理庞复的嵌套规则,优雅简洁

💡 成熟掌握两种思路,能使你展现多样化的解题技巧。

目录
相关文章
|
人工智能 自然语言处理 算法
Go语言统计字符串中每个字符出现的次数 — 简易频率分析器
本案例实现一个字符统计程序,支持中文、英文及数字,可统计用户输入文本中各字符的出现次数,并以整洁格式输出。内容涵盖应用场景、知识点讲解、代码实现与拓展练习,适合学习文本分析及Go语言基础编程。
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
850 90
|
存储 自然语言处理 算法
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
本文详细解析了力扣热题 208——实现 Trie(前缀树)。Trie 是一种高效的树形数据结构,用于存储和检索字符串集合。文章通过插入、查找和前缀匹配三个核心操作,结合 Go 语言实现代码,清晰展示了 Trie 的工作原理。时间复杂度为 O(m),空间复杂度也为 O(m),其中 m 为字符串长度。此外,还探讨了 Trie 的变种及应用场景,如自动补全和词典查找等。适合初学者深入了解 Trie 结构及其实际用途。
585 14
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
423 6
|
SQL 运维 监控
高效定位 Go 应用问题:Go 可观测性功能深度解析
为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
568 2
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
930 140
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1517 29
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
599 4
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

推荐镜像

更多
  • DNS