自己的做法
算法思想
使用两个栈,count栈一个放数字,chars放字符。
遍历字符串,有以下几种可能情况:
- 是数字,因为有可能是大于9的。那么就从当前字符开始,往后遍历,将遍历到的数字字符转换为数字加到num上,直到遇到第一个不是数字的字符,将num添加到count栈中
[
:直接入栈]
:遇到]
代表需要将该括号内的字符,循环counr.top()遍,所以chars依次出栈,并添加到temp字符串中,直到遇到[
(一定会遇到)。此时temp就是中括号内的字符串。这时有两种情况:- 栈不为空:说明该字符串序列嵌套在另一个中括号内,如"3[a2[b]]",那么就应该将temp字符串的字符循环count.top()遍,放入chars栈中
- 栈为空:说明该字符串序列并没有嵌套在其他中括号内,可以直接循环count.top()遍添加到结果字符串res中
- 字符:分两种情况:
- chars不为空:说明该字符在一个中括号内,直接入栈chars
- chars为空:说明该字符串是单独出现的,不需要循环。添加到res中
算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Solution { public: string decodeString(string s) { string res = ""; stack<char> chars; stack<int> count; for(int index = 0; index < s.size(); index++) { char ch = s[index]; if(isdigit(ch)) { int num = 0; while (isdigit(s[index])) { num = num * 10 + (s[index++] - '0'); } index--; count.push(num); } else if(ch == '[') { chars.push(ch); } else if(ch == ']') { string temp = ""; while (chars.top() != '[') { temp = chars.top() + temp; chars.pop(); } chars.pop(); if(!chars.empty()) { for(int i = 0; i < count.top(); i++) { for(int j = 0; j < temp.size(); j++) { chars.push(temp[j]); } } } else { for(int i = 0; i < count.top(); i++) { res += temp; } } count.pop(); } else { if(chars.empty()) { res.push_back(ch); } else { chars.push(ch); } } } return res; } };
|
性能分析
时间复杂度:O(n)。
空间复杂度:O(n)。
参考做法
参考给了两种做法,一种和我的类似,只不过它把数字和字母都放到同一个栈,数字紧挨着[
。
第二种用到了编译原理的知识。给出了一个LL(1)文法,根据FOLLOW集和FIRST集构造预测分析表。
学过编译原理,但只看懂了一部分。
留个坑。