394. Decode String
Given an encoded string, return it's decoded string.
The encoding rule is: k[encoded_string]
, where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.
You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.
Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a
or 2[4]
.
Examples:
s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
算法分析
看到 3[a2[c]]
这样的字符串,显然要用到递归算法,就是要把 []
中间的字符串解析出来后,再由外面的数字决定重复次数。而解析 []
中的字符串的过程,就是调用解析函数的过程。对于一个 encoded string, 我们把它考虑成如下的格式: (head)(body)(tail)
其中,head 是纯字符序列(当然也可能为空字符序列),body 是形如 3[ab2[c]]
的序列,tail 是之后的尾端字符序列;tail 可以看做一个独立的 encoded string。我们首先解析出 head,然后对 body 里方括号内的字符串调用解析函数,将得到的字符串重复 body 里打头的数字次数;然后解析 tail ,最后将三者合并即可。
Java算法:
public class Solution {
public String decodeString(String s) {
if(s==null||s.length()==0)
return s;
char ch;
int index=0;
int repeat=0;
StringBuilder head=new StringBuilder(""),body=new StringBuilder("");
while(index<s.length()&&!Character.isDigit(ch=s.charAt(index))){
head.append(ch);
index++;
}
if(index<s.length()){
//indicating that next character is Digit
while(index<s.length()&&Character.isDigit(ch=s.charAt(index))){
repeat=repeat*10+ch-'0';
index++;
}//got the leading num
//now index is pointing to '[';
//next, to get the index of ']';
int rightBracket=index+1;
int leftBracketNum=1;
while(leftBracketNum>0){
ch=s.charAt(rightBracket);
if(ch==']'){
leftBracketNum--;
}
else if(ch=='['){
leftBracketNum++;
}
else{
}
rightBracket++;
}
rightBracket--;//now rightBracket is pointing to the right position of the ']';
String bodyStr=decodeString(s.substring(index+1,rightBracket));
String tail=decodeString(s.substring(rightBracket+1));
for(int i=1;i<=repeat;i++){
body.append(bodyStr);
}
body.append(tail);
}
return head.toString()+body.toString();
}
}