我们需要解码一个经过编码的字符串,编码规则为k[encoded_string]
,表示方括号内的字符串encoded_string
重复k
次。字符串可能包含嵌套的编码格式。
算法思路
这个问题可以通过使用栈来辅助处理嵌套的编码字符串。具体步骤如下:
- 初始化栈:使用两个栈,一个用于存储当前的重复次数(数字栈),另一个用于存储当前的字符串(字符串栈)。
- 遍历字符串:
- 如果遇到数字,解析出完整的数字(因为数字可能不止一位)。
- 如果遇到左括号
[
,将当前的数字和字符串分别压入数字栈和字符串栈,然后重置当前数字和字符串。 - 如果遇到右括号
]
,从数字栈中弹出重复次数,从字符串栈中弹出之前的字符串,然后将当前字符串重复指定次数并拼接到之前的字符串后面。 - 如果遇到字母,直接将其添加到当前字符串中。
- 返回结果:遍历结束后,当前字符串即为解码后的结果。
Java实现
import java.util.Stack;
class Solution {
public String decodeString(String s) {
Stack<Integer> numStack = new Stack<>();
Stack<String> strStack = new Stack<>();
StringBuilder currentStr = new StringBuilder();
int num = 0;
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
} else if (c == '[') {
numStack.push(num);
strStack.push(currentStr.toString());
currentStr = new StringBuilder();
num = 0;
} else if (c == ']') {
int repeatTimes = numStack.pop();
StringBuilder temp = new StringBuilder(strStack.pop());
for (int i = 0; i < repeatTimes; i++) {
temp.append(currentStr);
}
currentStr = temp;
} else {
currentStr.append(c);
}
}
return currentStr.toString();
}
}
代码解释
- 初始化栈:
numStack
用于存储重复次数,strStack
用于存储之前的字符串。 - 遍历字符串:
- 数字处理:遇到数字时,构建完整的数字。
- 左括号处理:遇到
[
时,将当前数字和字符串压入栈,并重置。 - 右括号处理:遇到
]
时,弹出重复次数和之前的字符串,将当前字符串重复指定次数并拼接。 - 字母处理:遇到字母时,直接添加到当前字符串。
- 返回结果:最终
currentStr
即为解码后的字符串。
复杂度分析
- 时间复杂度:O(N),其中N是解码后字符串的长度。每个字符最多被处理一次。
- 空间复杂度:O(N),最坏情况下,栈的深度可能与字符串长度成正比。
简单总结
通过使用栈来处理嵌套的编码字符串,我们能够高效地解码字符串。数字栈和字符串栈分别用于存储重复次数和之前的字符串,确保在遇到右括号时能够正确地拼接和重复字符串。这种方法在时间和空间复杂度上都是最优的。