1、辅助栈
我们可以使用栈进行辅助。我们首先遍历整个数组:1、当读入数字时,我们继续读入所有数字并将其转化为字符串压入栈中;2、当读入字母或者“[”时,我们将当前字符入栈;3、当读入“]”时,我们将元素出栈直至“[”为栈顶元素,此时我们使用一个数组容纳所有出栈的字母,并将其转换顺序变为正序。接着我们将数字出栈,将当前的字符串重复多遍后再压入栈中进行循环。如此循环直至整个栈中都是字母为止,接着我们将所有元素出栈并转化为字符串即可。
class Solution {
public:
string getDigits(string &s, size_t &ptr) {
string ret = "";
while (isdigit(s[ptr])) {
ret.push_back(s[ptr++]);
}
return ret;
}
string getString(vector <string> &v) {
string ret;
for (const auto &s: v) {
ret += s;
}
return ret;
}
string decodeString(string s) {
vector <string> stk;
size_t ptr = 0;
while (ptr < s.size()) {
char cur = s[ptr];
if (isdigit(cur)) {
string digits = getDigits(s, ptr);
stk.push_back(digits);
} else if (isalpha(cur) || cur == '[') {
stk.push_back(string(1, s[ptr++]));
} else {
++ptr;
vector <string> sub;
while (stk.back() != "[") {
sub.push_back(stk.back());
stk.pop_back();
}
reverse(sub.begin(), sub.end());
stk.pop_back();
int repTime = stoi(stk.back());
stk.pop_back();
string t, o = getString(sub);
while (repTime--) t += o;
stk.push_back(t);
}
}
return getString(stk);
}
};
2、递归
我们从左到右遍历字符串:1、当前位置为数字时,说明后面的部分是需要重复的部分。我们首先记录需要重复输出的次数,而后调用函数返回其后部分组成的字符串;2、当当前位置为字母时,返回字母并继续递归调用函数;3、当当前位置为末尾或“]”时,返回空值。
class Solution {
public:
string src;
size_t ptr;
int getDigits() {
int ret = 0;
while (ptr < src.size() && isdigit(src[ptr])) {
ret = ret * 10 + src[ptr++] - '0';
}
return ret;
}
string getString() {
if (ptr == src.size() || src[ptr] == ']') {
return "";
}
char cur = src[ptr]; int repTime = 1;
string ret;
if (isdigit(cur)) {
repTime = getDigits();
++ptr;
string str = getString();
++ptr;
while (repTime--) ret += str;
} else if (isalpha(cur)) {
ret = string(1, src[ptr++]);
}
return ret + getString();
}
string decodeString(string s) {
src = s;
ptr = 0;
return getString();
}
};