394. 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例:
1 2 3
| s = "3[a]2[bc]", 返回 "aaabcbc". s = "3[a2[c]]", 返回 "accaccacc". s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
|
Solution1(递归法):
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
| class Solution { public: string decodeString(string s) { int i = 0; string ans = ""; while(i < s.size()){ ans += dfs(s,i); } return ans; } string dfs(string s, int &i){ int num = 0,flag = 0; string t = "", tt = ""; while(i < s.size() && s[i] >= '0' && s[i] <= '9'){ num = num * 10 + (s[i]-'0'); i++; } if(i < s.size() && s[i] == '[') flag = 1, i++; while(i < s.size() && s[i] != ']'){ if(s[i] >= '0' && s[i] <= '9'){ t += dfs(s,i); continue; } t += s[i]; i++; } if(t.size() > 0){ tt = t; while(--num > 0) tt += t; } if(i < s.size() && s[i] == ']') i++; return tt; } };
|
思路:
很正常的思路就是递归,每遇到数字就递归到下一层,等下一层的结束后,返回到当前层接着处理,在遇到’]’或者走到最后时,结束这一层的处理。
Solution2(栈):
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
| class Solution { public: string decodeString(string s) { stack<int> numstk; stack<string> strstk; int num = 0; string cur = ""; //当前层可以形成的串 for(int i = 0; i < s.size(); i++){ if(s[i] >= '0' && s[i] <= '9'){ num = num * 10 + (s[i]-'0'); }else if(s[i] == '['){ //模拟递归,该去下一层了。 numstk.push(num); strstk.push(cur); num = 0; cur = ""; }else if(s[i] == ']'){ //这一层已经完成处理 for(int j = 0; j < numstk.top(); j++){ strstk.top() += cur; } //返回上一层 cur = strstk.top(); strstk.pop(); numstk.pop(); }else{ cur += s[i]; } } return cur; } };
|
思路:
使用栈就是为了能保留当前层的信息,这里的进入下一层的时机和递归版略有差别,在到达’[‘的时候才进入下一层,主要是为了确定num的值和保存之前正处理的串的信息,在’]’的时候要处理完当前层,并且返回上一层。