字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入:s = “3[a]2[bc]”
输出:“aaabcbc”
解题思路
- 1、使用两个栈,一个用于存储重复次数,另一个用于存储临时结果。
- 2、遍历字符串,对于每个字符:
-
如果是数字,则将其转换为重复次数并入栈;
-
如果是左括号,则将当前结果入栈,并重置当前结果;
-
如果是右括号,则将栈顶的重复次数出栈,并将当前结果与出栈的重复次数拼接;
-
如果是字母,则将其拼接到当前结果中。
- 3、最终返回栈中的结果。
Java实现
public class DecodeString {
public String decodeString(String s) {
Stack<Integer> countStack = new Stack<>();
Stack<StringBuilder> currentResultStack = new Stack<>();
int count = 0;
StringBuilder currentString = new StringBuilder();
// 遍历字符串s的每个字符,对于每个字符ch:
for (char ch : s.toCharArray()) {
// 如果ch是数字,则将其转换为重复次数,并入栈countStack;
if (Character.isDigit(ch)) {
//ch - '0':这部分是将字符 ch 转换成对应的数字。
// 在 ASCII 编码中,数字字符 '0' 的 ASCII 值是 48,
// '1' 是 49,以此类推。所以,ch - '0' 就得到了字符对应的数字
count = count * 10 + (ch - '0');
} //如果ch是左括号,则将当前结果入栈resultStack,并重置当前结果为空;
else if (ch == '[') { //3[a2[c]]
countStack.push(count);
currentResultStack.push(currentString);
count = 0;
currentString = new StringBuilder();
} // 如果ch是右括号,则将栈顶的重复次数出栈,并将当前结果与出栈的重复次数拼接;
else if (ch == ']') {
int repeatCount = countStack.pop();
StringBuilder decodedString = new StringBuilder();
for (int i = 0; i < repeatCount; i++) {
decodedString.append(currentString);
}
currentString = currentResultStack.pop().append(decodedString);
} else {// 如果ch是字母,则将其拼接到当前结果中。
currentString.append(ch);
}
}
return currentString.toString();
}
public static void main(String[] args) {
DecodeString decoder = new DecodeString();
String encodedString = "3[a2[c]]";
String decodedString = decoder.decodeString(encodedString);
System.out.println("Decoded String: " + decodedString);
}
}
时间空间复杂度
-
时间复杂度:O(n),其中n为字符串s的长度。因为需要遍历字符串s一次。
-
空间复杂度:O(n),最坏情况下,需要额外的栈空间来存储重复次数和临时结果。