1、题目
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
* 示例 1:
* 输入:s = "3[a]2[bc]"
* 输出:"aaabcbc"
* 示例 2:
* 输入:s = "3[a2[c]]"
* 输出:"accaccacc"
2、思路
* 1 设置2个String栈,每遇到一个左括号就入括号栈,字符和数字累计入String栈
* 2 每遇到一个右括号就弹出栈顶和次栈顶,栈顶是要重复的字符,次栈顶是数字,循环后再入栈
* 3 数字的前面可能有多个字符,也应该累计起来入栈才能保证栈顶是要重复的字符
* 4 最后统一拼接
3、代码
class Solution {
public String decodeString(String s) {
int len = s.length();
Stack<String> numStrStack = new Stack<>(); //存放数字和字母
Stack<Character> strStack = new Stack<>(); // 存放括号
int flagDigit = 1, flagLetter = 1;
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (Character.isDigit(c) && Character.isDigit(s.charAt(i + 1))) { // 当前和下一个都是数字
flagDigit++;
} else if (i + 1 < len && Character.isLetter(c) && Character.isLetter(s.charAt(i + 1))) { //当前和下一个都是字母
flagLetter++;
} else if (Character.isDigit(c) && !Character.isDigit(s.charAt(i + 1))) { //当前是数字,下一个不是数字
numStrStack.push(s.substring(i - flagDigit+1, i+1));
flagDigit = 1;
} else if (i + 1 < len && Character.isLetter(c) && !Character.isLetter(s.charAt(i + 1))) {//当前是字母,下一个不是字母
numStrStack.push(s.substring(i - flagLetter+1, i+1));
flagLetter = 1;
} else if (i + 1 == len && Character.isLetter(c)) { //最后一个字母
numStrStack.push(s.substring(i - flagLetter+1, i+1));
flagLetter = 1;
} else {
if (c == '[') strStack.push(c);
else { //右括号
strStack.pop();
String tempStr = "";
while (Character.isLetter(numStrStack.peek().charAt(0))){ // 累加数字前面的字符
String str1 = numStrStack.pop();
tempStr = str1 + tempStr;
}
numStrStack.push(tempStr);
String tempLetter = numStrStack.pop();
int tempNum = Integer.parseInt(numStrStack.pop());
String str2= "";
for (int j = 0; j < tempNum; j++) { // 数字*字符
str2 += tempLetter;
}
numStrStack.push(str2);
}
}
}
String result = "";
while (!numStrStack.isEmpty()){ // 累加所有栈中的字符
String str3 = numStrStack.pop();
result = str3 + result;
}
return result;
}
}