字符串解码问题要求我们对经过特定规则编码的字符串进行解码。编码规则为 k[encoded_string]
,表示 encoded_string
需要重复 k
次。我们的任务是返回解码后的字符串。
示例:
-
输入:
s = "3[a]2[bc]"
输出:"aaabcbc"
-
输入:
s = "3[a2[c]]"
输出:"accaccacc"
问题难点:
- 括号可能存在嵌套,需要正确处理嵌套关系。
- 数字可能有多位,需要完整解析。
- 需要确保字符串的生成顺序正确。对于嵌套情况,需从内向外生成字符串。例如,在示例 2 中,先生成
cc
,再生成acc
。这种特性与栈的先进后出特性一致,因此可以使用栈来辅助处理。
算法思路:
- 使用两个栈:数字栈和字符串栈,分别存储当前数字和字符串状态。
- 遍历字符串
s
:- 如果当前字符
c
是数字,将其解析为当前数字,用于后续的字符串重复操作。 - 如果
c
是字母,直接拼接到当前字符串的末尾。 - 如果
c
是[
,表示一个重复块的开始,将当前状态(数字和字符串)压入栈中,并重置当前状态。 - 如果
c
是]
,表示一个重复块的结束,从栈中弹出数字和字符串,将当前字符串重复相应次数后拼接到弹出的字符串末尾,更新当前字符串。
- 如果当前字符
代码:
class Solution {
public:
string decodeString(string s) {
stack<int> numStack;
stack<string> strStack;
int curNum = 0;
string curStr;
for (char c:s) {
if (isdigit(c)) {
curNum = curNum * 10 + (c - '0');
}else if (c == '[') {
numStack.push(curNum);
curNum = 0;
strStack.push(curStr);
curStr.clear();
}else if (c == ']') {
int k = numStack.top();
numStack.pop();
string preStr = strStack.top();
strStack.pop();
string temp;
for (int i = 0;i < k;i++) {
temp += curStr;
}
curStr = preStr + temp;
}else {
curStr += c;
}
}
return curStr;
}
};
时间复杂度:O(n),其中 n 为字符串 s 的长度,算法仅需一次遍历即可完成。
空间复杂度:O(n),在最坏情况下(如处理类似 3[3[3[3[3[a]]]]]
的嵌套结构时),存储栈需要线性空间。