【Leetcode】394. 字符串解码

154 阅读2分钟

题目描述

在这里插入图片描述

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: 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();
    }
}