Given an encoded string, return its 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”.
k[encoded_string]表示把encode_string重复k次,原字符串中不含数字
思路:
有括号匹配问题所以用Stack,用两个Stack,一个用来放数字,一个用来放字符串,
当遇到" [ “时,push入数字和之前的字符串,push之后要把之前保存数字和字符串的临时变量清空,遇到连续数字时要记得用十进制法相加。
遇到” ] "时,从两个Stack中分别pop出数字和字符串,把字符串复制k次
注意遇到" [ “时,数字是” [ “之前的数字,而对应的字符串是在” [ “后面的,也就是数字对应的字符串是保存在临时变量中的
比如s = “3[a2[c]]”, 遇到第一个” [ “,数字Stack中push进3,但是string的Stack是”",遇到第二个" [ “时,数字Stack中再push进2,string的Stack中push进之前的“a”
遇到第一个” ] “时,c是保存在tmp变量中的,因为“c”后面没有” [ “,所以“c“没有进Stack,这时要把tmp的”c“复制2次,再从Stack中pop出a,把复制好的”cc“接在”a后面,把“acc”保存进tmp变量,这样在下一步遇到” ] "时仍可以重复这个操作。
为节省临时字符串变量tmpStr的Object建立,用StringBuilder
public String decodeString(String s) {
if(s == null || s.length() == 0) {
return s;
}
Stack<Integer> stNum = new Stack<>();
Stack<String> stStr = new Stack<>();
StringBuilder tmpStr = new StringBuilder();
int cnt = 0;
String result = "";
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
cnt = cnt * 10 + s.charAt(i) - '0';
} else if(s.charAt(i) == '[') {
stNum.push(cnt);
stStr.push(tmpStr.toString());
cnt = 0;
tmpStr.delete(0, tmpStr.length());
} else if(s.charAt(i) == ']') {
result = stStr.pop();
int end = 1;
if(stNum.peek() != null) {
end = stNum.pop();
}
for(int k = 0; k < end; k++) {
result += tmpStr.toString();
}
tmpStr.delete(0, tmpStr.length());
tmpStr.append(result);
} else {
tmpStr.append(s.charAt(i));
}
}
return tmpStr.toString();
}
下面这样写更易懂,但是运行时间比上面的版本长
public String decodeString(String s) {
if(s == null || s.length() == 0) {
return s;
}
Stack<Integer> stNum = new Stack<>();
Stack<String> stStr = new Stack<>();
String tmpStr = "";
int cnt = 0;
String result = "";
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
cnt = cnt * 10 + s.charAt(i) - '0';
} else if(s.charAt(i) == '[') {
stNum.push(cnt);
stStr.push(tmpStr);
cnt = 0;
tmpStr = "";
} else if(s.charAt(i) == ']') {
result = stStr.pop();
int end = stNum.pop();
for(int k = 0; k < end; k++) {
result += tmpStr;
}
tmpStr = result;
} else {
tmpStr += s.charAt(i);
}
}
return tmpStr;
}