思路:建立一个最终要返回的字符串res,置其初值为空字符串"",建立两个栈,一个用来存放数字的数字栈,一个用来存放字符串的字符串栈,遍历题目给的字符串,当遍历到的字符为数字的时候,将其加入到数字栈中(为什么创建一个栈独立存放数字,因为数字不一定是个位数,它可能是任意位数,如果只用一个栈来同时存放数字与字符串可能不好理解,我们方便理解可以直接新创一个栈用来存放数字)当遍历到的字符为字母时,将其连接到res中去,当遍历到的字符为左括号[时,先将前面的字符串res存放到字符串栈中,然后再将res置为空串"",当其遍历到右括号]时,先建立一个临时的字符串temp,temp的初始值等于从字符串栈中出栈的字符串,然后从数字栈中出栈一个数字,这个数字就是temp要重复连接res的次数,temp循环遍历要重复的次数,每次都加上res,相当于res重复了几遍,循环完成再令res等于temp的值。
可能会想不通的地方
1、关于为什么遇到左括号时当前的res要入栈,我们这里举一个例子来方便理解,如果字符串为3[a2[c]]时,遍历到第二个[时,如果不把当前的res(a)入栈,后面遇到第一个]时,其实应该是将c重复两遍,但是此时就变成了ac重复两遍了。
2、为什么temp的初始值要等于从字符串栈中出栈的字符串呢,会不会造成嵌套括号的情况错乱呢,其实也不会,我们举例子来理解,3[a]2[bc]当遇到第二个]时,我们的操作是先令temp=aaa,然后再循环两遍,每一遍都将bc连接到aaa后面,对于3[a2[c]],我们先将temp=aaa然后再循环两次每一次都将c连接到temp后面,然后再将aaacc循环三遍,注意res是我们最终要返回的字符串,还是不理解的话可以结合例子自己画图一步一步推到底理解一下。
class Solution {
public String decodeString(String s) {
String res="";
Stack<Integer> CountStack=new Stack<Integer>();
Stack<String> resStack=new Stack<String>();
int idx=0;
while(idx<s.length()){
char curr=s.charAt(idx);
if(Character.isDigit(curr)){
//Character.isDigit(curr)判断curr是不是数字
StringBuffer ret=new StringBuffer();
while(Character.isDigit(s.charAt(idx))){
ret.append(s.charAt(idx));
idx++;
}
CountStack.push(Integer.parseInt(ret.toString()));
}
else if(curr=='['){
resStack.push(res);
res="";
idx++;
}else if(curr==']'){
StringBuffer temp=new StringBuffer(resStack.pop());
int repeattime=CountStack.pop();
for(int i=0;i<repeattime;i++){
temp.append(res);
//temp.append(res)意思是将res连接到temp后面
}
res=temp.toString();
idx++;
}
else {
res+=s.charAt(idx);
idx++;
}
}
return res;
}
}