题目链接
题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入: s = “3[a]2[bc]”
输出: “aaabcbc”
示例 2:
输入: s = “3[a2[c]]”
输出: “accaccacc”
示例 3:
输入: s = “2[abc]3[cd]ef”
输出: “abcabccdcdcdef”
示例 4:
输入: s = “abc3[cd]xyz”
输出: “abccdcdcdxyz”
解题思路
方法一:栈
- 构建辅助栈
stack, 遍历字符串s中每个字符c;- 当
c为数字时,将数字字符转化为数字multi,用于后续倍数计算; - 当
c为字母时,在res尾部添加c; - 当
c为[时,将当前multi和res入栈,并分别置空置 0:- 记录此
[前的临时结果res至栈,用于发现对应]后的拼接操作; - 记录此
[前的倍数multi至栈,用于发现对应]后,获取multi × [...]字符串。 - 进入到新
[后,res和multi重新记录。
- 记录此
- 当
c为]时,stack出栈,拼接字符串res = last_res + cur_multi * res,其中:last_res是上个[到当前[的字符串,例如"3[a2[c]]"中的a;cur_multi是当前[到]内字符串的重复倍数,例如"3[a2[c]]"中的2。
- 当
- 返回字符串
res。class Solution {public String decodeString(String s) {// 记录结果 last_resStringBuilder ans = new StringBuilder();// 记录倍数Deque<Integer> mutilStack = new LinkedList<>();// 记录字符串Deque<StringBuilder> ansStack = new LinkedList<>();// 倍数int mutil = 0;for(char c : s.toCharArray()){// 如果是数字,则说明是倍数(下一个[]的倍数),记录倍数if(Character.isDigit(c)){mutil = mutil * 10 + (c - '0');// [ 表示当前为一个新的需要解码的字符串,先将之前的字符串和// 倍数(下一个[]的倍数)存到栈中,从新记录}else if(c == '['){ansStack.push(ans);mutilStack.push(mutil);ans = new StringBuilder();mutil=0;// ] 表示当前字符串结束,可以解码}else if(c == ']'){// 倍数前面的 字符串StringBuilder ansTmp = ansStack.poll();// 当前 字符串 需要的倍数int mutilTmp = mutilStack.poll();for(int i = 0; i < mutilTmp; ++i){ansTmp.append(ans);}// 当前结果ans = ansTmp;}else{ans.append(c);}}return ans.toString();}}
class Solution {String s;public String decodeString(String s) {this.s = s;return recur(0, s.length() - 1);}private String recur(int pos, int right){if(pos > right){return "";}String res = "";int left;// 当前是字符串if(s.charAt(pos) >='a' && s.charAt(pos) <='z'){left = pos;while(pos <= right && s.charAt(pos) >='a' && s.charAt(pos) <='z'){++pos;}res += s.substring(left, pos);}// 当前是倍数int n = 0;while(pos <= right && s.charAt(pos) >= '0' && s.charAt(pos) <= '9'){n = n * 10 + s.charAt(pos) - '0';++pos;}++pos;int l = 1, r = 0;left = pos;// 当前倍数范围while(pos <= right && l != r){if(s.charAt(pos) == '['){++l;}else if(s.charAt(pos) == ']'){++r;}++pos;}// 返回结果为当前字符串 + 递归解析当前倍数 + 递归解析当前倍数后面的字符串return res + recur(left, pos - 2).repeat(n) + recur(pos, right);}}
- 时间复杂度 O(n)
- 空间复杂度 O(n)
