字符串解码
题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
1:辅助栈
这个题可以先参考下leetcode的第20题:有效的括号。使用的都是辅助栈操作。
- 解码顺序问题,对于非嵌套括号的可以按顺序来进行解码;当出现嵌套括号时,一般情况是先对内层的括号进行解码
- 如何去判断内层括号与外层的括号。利用栈来判断第一个
]
出现的时候,说明内层的括号关闭了,这时候应该解码出内层括号里面的内容 - 在遍历的过程中
- 字符为数字,解析数字(注意连续数字的情况)存入
num
- 字符为
[
,把之前得到的数字num
和 字母str
分别压栈,然后把数字重置为0,字母字符串重置为空串 - 字符为字母,拼接字母 存入
str
- 字符为
]
,,数字栈栈顶数字出栈,作为重复次数 n,字母栈栈顶字母出栈,作为前缀字母字符串去拼接str
字母变量,总共拼接 n 次,拼接后的新字母串给str
- 字符为数字,解析数字(注意连续数字的情况)存入
/**
* 例如:
* 2[abc]3[cd]ef
* ↑
* 遇到左括号,把数字 num=2 和 字母 str="" 入栈,并且 num 和 str 重置
* | | | |
* | | | |
* |_2_| |_""_|
* numStack strStack
*
* 2[abc]3[cd]ef
* ↑
* 遇到左括号,num=0 str="abc",numStack 和 strStack 栈顶元素出栈 str = strStack.pop() + str \* numStack.pop() = "" + "abc" * 2 = "abcabc"
* | | | |
* | | | |
* |___| |___|
* numStack strStack
*
* 2[abc]3[cd]ef
* ↑
* 遇到右括号,数字 num=3 和 字母 str="abcabc" 入栈,并且 num 和 str 重置
* | | | |
* | | | |
* |_3_| |_abcabc_|
* numStack strStack
*
* 2[abc]3[cd]ef
* ↑
* 遇到左括号,num=0 str=cd,numStack 和 strStack 栈顶元素出栈 str = "abcabc" + "cd" * 3 = "abcabccdcdcd"
* | | | |
* | | | |
* |_3_| |_abcabc_|
* numStack strStack
*
* 遍历结束,最终结果 str="abcabccdcdcdef"
*/
class Solution {
public String decodeString(String s) {
// 两个辅助栈,一个用来存放数字,另外一个用来存放字符串
LinkedList<String> strStack = new LinkedList<>();
LinkedList<Integer> numStack = new LinkedList<>();
int index = 0;
int len = s.length();
int num = 0;
StringBuilder str = new StringBuilder();
while(index < len) {
char tmp = s.charAt(index);
// 数字,转换类型char->int
if(Character.isDigit(tmp)) {
num = num * 10 + tmp - '0';
} else if(
// 字符
Character.isLowerCase(tmp) || Character.isUpperCase(tmp)) {
str.append(tmp);
} else if(tmp=='[') {
// 入栈
strStack.push(str.toString());
numStack.push(num);
str = new StringBuilder();
num = 0;
} else {
// 出栈
StringBuilder preSB = new StringBuilder().append(strStack.pop());
int times = numStack.pop();
for (int j = 0; j < times; j++) {
preSB.append(str);
}
str = preSB;
}
index++;
}
return str.toString();
}
}