「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
题目
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
来源:力扣(LeetCode)
思路
1.看到这道题第一感觉应该和括号匹配问题有些类似,遇到的字符有这几种类型
- [
- ]
- 0~9
- a~z
2.实际上最早的字符串应该是从内部最想匹配生成的,比如3[a2[c]]里面的2c要比外面的3[a2[c]]先组成字符串,每次遇到]的情况就是说明一次新的字符串构建的过程
3.用一个栈numStack存储遇到的数字,一个栈strStack存储拼接成的字符串
4.分类讨论各种情况
-
[
说明开始进入一个新的匹配阶段,需要保留上一次字符串拼接的结果以及上一次字符串前面的数
然后需要把num和res都变成初始值
numStack.addLast(num);
strStack.addLast(res.toString());
res = new StringBuilder();
num = 0;
-
]
说明可以开始匹配了,从保存次数的numStack栈顶取出个数,然后进行字符串的拼接
-
0~9 只需要更新num的值即可,需要注意进位
num = num * 10 + Integer.parseInt(c + "");
- a~z
直接添加到res中
代码
class Solution {
public String decodeString(String s) {
StringBuilder res = new StringBuilder();
char[] chars = s.toCharArray();
LinkedList<Integer> numStack = new LinkedList<>();
LinkedList<String> strStack = new LinkedList<>();
int num = 0;
for (char c : chars) {
if (c == '[') {
numStack.addLast(num);
strStack.addLast(res.toString());
res = new StringBuilder();
num = 0;
} else if (c == ']') {
StringBuilder temp1 = new StringBuilder();
int times = numStack.removeLast();
for (int i = 0; i < times; i++) {
temp1.append(res);
}
res = new StringBuilder(strStack.removeLast() + temp1);
} else if (c >= '0' && c <= '9') {
num = num * 10 + Integer.parseInt(c + "");
} else { //普通符号
res.append(c);
}
}
return res.toString();
}
}