【队列 &栈】day18_394. 字符串解码

76 阅读1分钟

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

编码规则为: 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"

 

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300]

题解

思路:栈

1.遍历s,元素为数字(考虑多位数情况)、[、字母时入栈,元素为]出栈

2.一直出栈到元素为[,这之间的字符串str为加密字符串,再将[及次数k出栈,最后将重复k次的str入栈

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public String decodeString(String s) {
        Deque<String> res = new LinkedList<>();
        Deque<String> encoded = null;

        for (int i = 0; i < s.length(); i++) {
            char cur = s.charAt(i);
            if (Character.isDigit(cur)) {
                // 次数k
                String k = getDigits(i, s);
                res.offer(k);
                i += k.length() - 1;
            } else if (cur == '[' || Character.isLetter(cur)) {
                res.offer(String.valueOf(cur));
            } else {
                encoded = new LinkedList<>();
                while (!Objects.equals(res.peekLast(), "[")) {
                    encoded.offerFirst(res.pollLast());
                }
                // [ 出栈
                res.pollLast();

                String str = getStr(encoded);

                // 获取k
                int k = Integer.parseInt(res.pollLast());
                for (int j = 1; j <= k; j++) {
                    res.offer(str);
                }
            }
        }
        return getStr(res);
    }

    public String getDigits(int i, String s) {
        StringBuilder sb = new StringBuilder();
        while (Character.isDigit(s.charAt(i))) {
            sb.append(s.charAt(i++));
        }
        return sb.toString();
    }

    public String getStr(Deque<String> encoded) {
        StringBuilder sb = new StringBuilder();
        while (!encoded.isEmpty()) {
            sb.append(encoded.pollFirst());
        }
        return sb.toString();
    }
}