题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
题解
执行用时:1 ms, 在所有 Java 提交中击败了84.85%的用户
内存消耗:36.4 MB, 在所有 Java 提交中击败了62.10%的用户
// ↓
// "3[a]2[bc]"
// multi = 3 res = ""
// stackInt = []
// stackStr = []
// ↓
// "3[a]2[bc]"
// multi = 0 res = ""
// stackInt = [3]
// stackStr = [""]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "a"
// stackInt = [3]
// stackStr = [""]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "a" temp = "aaa"
// stackInt = [3]
// stackStr = [""]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "aaa" temp = "aaa"
// stackInt = [3]
// stackStr = [""]
// ↓
// "3[a]2[bc]"
// multi = 2 res = "aaa" temp = "aaa"
// stackInt = [3]
// stackStr = [""]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "" temp = "aaa"
// stackInt = [3,2]
// stackStr = ["aaa"]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "b" temp = "aaa"
// stackInt = [3,2]
// stackStr = ["aaa"]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "bc" temp = "aaa"
// stackInt = [3,2]
// stackStr = ["aaa"]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "bc" temp = ""
// stackInt = [3,2]
// stackStr = ["aaa"]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "bc" temp = "bcbc"
// stackInt = [3,2]
// stackStr = ["aaa"]
// ↓
// "3[a]2[bc]"
// multi = 0 res = "aaabcbc" temp = "bcbc"
// stackInt = [3,2]
// stackStr = ["aaa"]
class Solution {
public String decodeString(String s) {
Stack<Integer> stackInt = new Stack<>(); // 存储a[xx]中的a,即中括号中字符串需要重复的次数(的先后关系)
Stack<String> stackStr = new Stack<>(); // stackStr用来存储需要拼接的字符串(的先后关系)
StringBuilder res = new StringBuilder(); // res用来存最终结果,和中途a[xx]需要被重复a次的基底字符串
int multi = 0; // 记录
for (Character c : s.toCharArray()) {
if (c >= '0' && c <= '9') {
multi = multi * 10 + Integer.parseInt(String.valueOf(c)); // + multi*10是保证数字即使是非个位数,也能正确取到
}
else if (c == '[') { // 遇到[,把multi存入栈,把(之前搜集的字符串)res存入栈,清空res
stackInt.push(multi);
stackStr.push(res.toString());
multi = 0;
res = new StringBuilder();
}
else if (c == ']') { // 遇到]之后,此时需要重复的基底字符串是res,重复次数在stackInt中,把res字符重复stackInt.pop()次
int index = stackInt.pop();
StringBuilder temp = new StringBuilder();
for (int i = 0; i < index; i++) temp.append(res);
res = new StringBuilder(stackStr.pop() + temp);
}
else { // 在[]之中,把需要重复的基底字符串暂时存入res
res.append(c);
}
}
return res.toString();
}
}