题目
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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"
分析
栈可以帮助我们处理嵌套的编码结构,当遇到左括号时,将之前的状态(包括当前的重复次数和已经解码的字符串)压入栈中,当遇到右括号时,从栈中弹出之前的状态并进行解码操作。
辅助栈
整体思路
遇到数字:如果当前字符是数字,将其转换为整数并更新 k
。由于重复次数可能是多位数,需要将之前的结果乘以 10 再加上当前数字。
遇到左括号:将当前的重复次数 k
压入 countStack
,将当前字符串 currentString
压入 stringStack
,然后重置 currentString
和 k
。
遇到右括号:从 countStack
中弹出重复次数 repeatCount
,从 stringStack
中弹出之前的字符串 decodedString
。将 currentString
重复 repeatCount
次并添加到 decodedString
中,更新 currentString
。
遇到普通字符:将当前字符添加到 currentString
中。
时间复杂度:O(),
是输入字符串的长度
空间复杂度:O(),
是栈的最大深度
class Solution {
public:
string decodeString(string s) {
std::stack<int> countStack;
std::stack<std::string> stringStack;
std::string currentString;
int k = 0;
for (char ch : s) {
if (std::isdigit(ch)) {
// 处理数字,可能是多位数
k = k * 10 + (ch - '0');
} else if (ch == '[') {
// 遇到左括号,将重复次数和当前字符串压入栈中
countStack.push(k);
stringStack.push(currentString);
// 重置当前字符串和重复次数
currentString = "";
k = 0;
} else if (ch == ']') {
// 遇到右括号,进行解码操作
std::string decodedString = stringStack.top();
stringStack.pop();
int repeatCount = countStack.top();
countStack.pop();
for (int i = 0; i < repeatCount; ++i) {
decodedString += currentString;
}
currentString = decodedString;
} else {
// 遇到普通字符,添加到当前字符串中
currentString += ch;
}
}
return currentString;
}
};
知识充电
isdigit() 函数
isdigit
函数是 C 和 C++ 标准库中的一个字符处理函数,用于判断一个字符是否为十进制数字字符。isdigit
函数用于检查传入的字符 c
是否为十进制数字字符,也就是字符 '0'
到 '9'
中的任意一个。如果 c
是十进制数字字符,函数返回一个非零值(通常为非零整数,表示真);如果 c
不是十进制数字字符,函数返回 0(表示假)。
#include <iostream>
#include <cctype>
int main() {
char ch1 = '5';
char ch2 = 'A';
if (std::isdigit(ch1)) {
std::cout << ch1 << " 是一个数字字符。" << std::endl;
} else {
std::cout << ch1 << " 不是一个数字字符。" << std::endl;
}
if (std::isdigit(ch2)) {
std::cout << ch2 << " 是一个数字字符。" << std::endl;
} else {
std::cout << ch2 << " 不是一个数字字符。" << std::endl;
}
return 0;
}