给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
示例 1:
输入:s = "3[a]2[bc]" 输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]" 输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef" 输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz" 输出:"abccdcdcdxyz"
提示:
1 <= s.length <= 30
s
由小写英文字母、数字和方括号'[]'
组成s
保证是一个 有效 的输入。s
中所有整数的取值范围为[1, 300]
这个题目官方推荐使用栈来解,我这里使用的是递归的方式,如果理解不了的话可以去官方题解理解一下他们给的答案
class Solution {
public String decodeString(String s) {
char[] sArr = s.toCharArray();
return process(sArr, 0).result;
}
/**计算从curIndex开始的结果,这个结算过程中会用到一些中间的过程,计算遇到]就结束当前段*/
public Info process(char[] sArr, int curIndex) {
StringBuilder result = new StringBuilder();
if(curIndex >= sArr.length) {
return null;
}
if(sArr[curIndex] == ']') {
/**如果遇到右括号,结束本段调用*/
return new Info("", curIndex);
} else if(sArr[curIndex] >= '0' && sArr[curIndex] <= '9') {
/**遇到数字进行累加 */
int curNum = 0;
/**数字后面一定是左括号,这是题目规定的 */
while(sArr[curIndex] >= '0' && sArr[curIndex] <= '9') {
curNum = curNum * 10 + (sArr[curIndex++] - '0');
}
/**当前curIndex是左括号的位置 */
Info nextInfo = process(sArr, curIndex + 1);
for(int i = 0; i < curNum; i++) {
result.append(nextInfo.result);
}
/**算到哪了继续算*/
Info restInfo = process(sArr, nextInfo.endIndex + 1);
/**按题目规定 */
return new Info(result.append(restInfo == null? "" : restInfo.result).toString(), restInfo == null? nextInfo.endIndex : restInfo.endIndex);
} else {
while(curIndex < sArr.length && sArr[curIndex] >= 'a' && sArr[curIndex] <= 'z') {
result.append(sArr[curIndex++]);
}
/**字母之后必定是右括号,我们直接跳了,注意这里的下标是curIndex+1,因为curIndex已经是右括号了 */
Info nextInfo = process(sArr, curIndex);
/**注意这里是curIndex-1,因为curInex不是字母才返回的 */
return new Info(result.append(nextInfo == null? "" : nextInfo.result).toString(), nextInfo == null? curIndex : nextInfo.endIndex);
}
}
/**顶一个一个递归过程的结果类,result表示当前段的结果,endIndex表示这个结果是算到了哪个位置结束 */
static class Info {
String result;
int endIndex;
public Info(String result, int endIndex) {
this.result = result;
this.endIndex = endIndex;
}
}
}