🧮 Algorithm Notebook
1、算法准备
1.1 牛客网编程OJ的典型输入输出
2、算法框架
2.1 动态规划
2.1.1 斐波那契数列
2.1.2 背包问题
2.1.3 贪心算法
2.1.4 序列和数组类问题
2.1.5 编辑距离
2.1.6 高楼扔鸡蛋
2.1.7 股票问题系列通解
2.1.8 最长有效括号
2.1.9 剪绳子
2.1.10 正则表达式匹配
2.2 二分查找
2.2.1 二分查找框架
2.2.2 搜索旋转排序数组
2.3 链表
2.3.1 反转链表
2.3.2 相交链表
2.3.3 合并链表
2.3.4 链表中倒数第k个节点
2.3.5 复制带随机指针的链表
2.4 排序算法
2.4.1 常见排序算法
2.5 二叉树
2.5.1 二叉树遍历
2.5.2 岛屿问题
2.5.3 二叉树路径问题
2.5.4 构造二叉树
2.6 回溯算法
2.6.1 回溯算法解题框架
2.6.2 N皇后
2.7 数组
2.7.1 删除有序数组中的重复项
2.7.2 滑动窗口最大值
2.7.3 调整数组顺序使奇数位于偶数前面
2.7.4 螺旋矩阵
2.7.5 多数元素
2.7.6 最大数
2.7.7 和为s的两个数字
2.7.8 构建乘积数组
2.7.9 两数之和
2.8 字符串
2.8.1 最小覆盖子串
2.8.2 比较版本号
2.8.3 验证IP地址
2.8.4 基本计算器 II
2.8.5 字符串解码
2.8.6 移掉 K 位数字
2.8.7 无重复字符的最长子串
2.8.8 第一个只出现一次的字符
2.8.9 翻转字符串里的单词
2.8.10 字符串转换整数 (atoi)
2.8.11 字符串四则运算
2.9 栈
2.9.1 最小栈
2.9.2 弹出序列
2.10 数学
2.10.1 用 Rand7() 实现 Rand10()
2.10.2 只出现一次的数字
2.10.3 整数反转
2.10.4 求1+2+…+n
2.10.5 二进制中1的个数
2.10.6 幂运算
2.10.7 1~n 整数中 1 出现的次数
2.10.8 数字序列中某一位的数字
2.10.9 丑数
2.10.10 n个骰子的点数
2.10.11 圆圈中最后剩下的数字
2.10.12 不用加减乘除做加法
2.10.13 x 的平方根
2.11 设计
2.11.1 LRU 缓存机制
-
+
游客
注册
登录
字符串解码
## 1 题目 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 **示例 1:** ```txt 输入:s = "3[a]2[bc]" 输出:"aaabcbc" ``` **示例 2:** ```txt 输入:s = "3[a2[c]]" 输出:"accaccacc" ``` **示例 3:** ```txt 输入:s = "2[abc]3[cd]ef" 输出:"abcabccdcdcdef" ``` **示例 4:** ```txt 输入:s = "abc3[cd]xyz" 输出:"abccdcdcdxyz" ``` ## 2 问题分析 1. **构建两个辅助栈 $lastMultiStack$**、$lastResStack$,**分别用于临时存放 `[` 前的遍历的倍数和结果**。 2. **遍历字符串 $s$ 中的每个字符 $c$**: 1. **当 $c$ 为数字时**: 1. **将数字字符转化为数字 $multi$**,**用于后续倍数计算**。 ![](/media/202206/2022-06-07_153357_250179.png) 2. **当 $c$ 为字母时**: 1. **在 $res$ 尾部添加 $c$**。 ![](/media/202206/2022-06-07_153438_472342.png) 3. **当 $c$ 为 `[` 时**: 1. **记录此 `[` 前的临时结果 $res$ 入栈**,**用于发现对应 `]` 后的拼接操作**。 2. **记录此 `[` 前的倍数 $multi$ 入栈**,**用于发现对应 `]` 后**,**获取 $multi \times [\cdots]$ 字符串**。 3. **将 $res$**、**$multi$ 分别置空置 0**。 ![](/media/202206/2022-06-07_153504_034646.png) 4. **当 $c$ 为 `]` 时**: 1. **$lastResStack$ 出栈**,**获取 $lastRes$**。 2. **$lastMultiStack$ 出栈**,**获取 $currentMulti$**。 3. **拼接字符串 $res = lastRes + currentMulti \times res$**。 ![](/media/202206/2022-06-07_153534_738665.png) 3. **返回字符串 $res$**。 ![](/media/202206/2022-06-07_153313_011567.gif) ## 3 参考代码 ```java /** * 394. 字符串解码 * @param s 编码后的字符串 * @return 解码后的字符串 */ public String decodeString(String s) { // 最后结果 StringBuilder res = new StringBuilder(); // 数字栈 LinkedList<Integer> lastMultiStack = new LinkedList<>(); // 临时结果栈 LinkedList<String> lastResStack = new LinkedList<>(); // 临时数字 int multi = 0; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '[') { /** * 如果当前字符为 [,则: * 1. 将当前 multi 和 res 入栈。 * 2. 分别将 multi、res 置空置 0 */ lastMultiStack.addLast(multi); lastResStack.addLast(res.toString()); multi = 0; res = new StringBuilder(); } else if (c == ']') { /** * 如果当前字符为 ],则: * 1. lastResStack 出栈,获取 lastRes。 * 2. lastMultiStack 出栈,获取 currentMulti。 * 3. res = lastRes + currentMulti * res */ String lastRes = lastResStack.removeLast(); StringBuilder tmp = new StringBuilder(); int currentMulti = lastMultiStack.removeLast(); for (int j = 0; j < currentMulti; j++) {tmp.append(res);} res = new StringBuilder(lastRes + tmp); } else if (c >= '0' && c <= '9') { /** * 如果当前字符为数字,则: * 1. 将数字字符转化为数字 multi */ multi = multi * 10 + c - '0'; } else { /** * 如果当前字符为字母,则: * 1. 在 res 尾部添加 c */ res.append(c); } } // 返回最后的结果 return res.toString(); } ``` ## 参考文献 1. [394. 字符串解码](https://leetcode-cn.com/problems/decode-string)。 2. [字符串解码(辅助栈法 / 递归法,清晰图解)](https://leetcode-cn.com/problems/decode-string/solution/decode-string-fu-zhu-zhan-fa-di-gui-fa-by-jyd)。
ricear
2022年6月7日 16:02
©
BY-NC-ND(4.0)
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码