leetcode 394
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
输入:s = “3[a]2[bc]”
输出:“aaabcbc”
算法思想:
该字符串一共有四种情况,分别是数字,字母,左括号,右括号
分情况进行讨论:
首先如果遇到数字,利用num对该数字进行存储(注意这里数字是char需要转换成int)
if(s[i]>='0'&&s[i]<='9')
{
num=10*num+s[i]-'0';
}
如果是字母,我们定义一个字符串cur来对其进行记录
else if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z'))
{
cur+=s[i];
}
如果是左括号,我们讲收集到的cur压入栈中,同时将数字num也压入栈中,再将cur清空
else if(s[i]=='[')
{
nums.push(num);
ss.push(cur);
num=0;
cur.clear();
}
如果是右括号,则将数字栈中的顶端弹出定义为k,将此时收集到的cur*k加在栈的顶部(此时的cur是括号里的字符串,栈顶部的字符串是左括号前面的字符串)
else if(s[i]==']')
{
int k=nums.top();
nums.pop();
for(int i=0;i<k;i++)
{
ss.top()+=cur;
}cur=ss.top();
ss.pop();
}
最后的res就是解码后的字符串
图示:
举例:a3[b2[c]]x4[d]
解码出来为:abccbccbccxdddd
遍历到数字3时:cur=‘a’ ,num=3;
遍历到第一个左括号后:栈的示意图
继续遍历遍历到数字2时:cur=‘b’,num=2;
第二个左括号:
遍历到第一个右括号时:
弹出数字栈顶元素
此时cur=‘c’,k=nums.top()=2;
ss.top()=ss.top()+cur*k,
执行完for循环后;
ss.top=bcc;
之后cur=ss.top();将栈顶元素弹出;
此时cur=bcc;
第一个右括号操作完成;
遇到第二个右括号,同理进行操作,执行完for循环后
再将ss.top弹出,cur=ss.top;
此时字符串栈,数字栈都无元素
cur=abccbccbcc;
接着遇到第三个左括号,
此时cur=abccbccbccx;num=4;
将其压入栈后清空cur与num,此时两个栈如图:
遇到第三个右括号,
执行完for循环后
ss.top()=abccbccbccxdddd;(数字栈中无元素);
之后cur=ss.top();
将ss栈顶元素弹出,字符串遍历完成,得到cur=abccbccbccxdddd为最终答案;
解题代码
class Solution {
public:
string decodeString(string s) {
int len=s.size();
int num=0;
stack<int> nums;
stack<string> ss;
string cur="";
for(int i=0;i<len;i++)
{
if(s[i]>='0'&&s[i]<='9')
{
num=10*num+s[i]-'0';
}
else if(s[i]=='[')
{
nums.push(num);
ss.push(cur);
num=0;
cur.clear();
}
else if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z'))
{
cur+=s[i];
}
else if(s[i]==']')
{
int k=nums.top();
nums.pop();
for(int i=0;i<k;i++)
{
ss.top()+=cur;
}cur=ss.top();
ss.pop();
}
}
return cur;
}
};