880. Decoded String at Index, medium, stack

思路1

直接用String把字符串拼起来。

public String decodeAtIndex(String S, int K) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);

            if (Character.isDigit(c)) {
                int num = Character.getNumericValue(c);
                String s = sb.toString();
                for (int k = 0; k < num-1; k++) {
                    sb.append(s);
                }
                continue;
            }

            if (Character.isAlphabetic(c)) {
                sb.append(c);
                continue;
            }

            System.out.println("出错了");
        }

        return Character.toString(sb.charAt(K-1));
    }

问题:内存溢出,因为字符串会指数级增长。

思路2

用一个结构node代表字符串,包括:node的指针(代表前面的字符串),字符串,重复次数,目前整体长度。
可以用栈表示,前面的字符在栈底,新的字符在栈顶。
用数字把S分隔开。每个节点存储一个字符串片段,并记录重复的次数,总长度。我有点乱。
K从0开始好计算,K = K - 1
计算当前节点重复前的长度,把K round到这个数之间。然后判断要找的位置在当前片段还是前面的节点。
计算当前节点字符串片段代表的位置。

class Solution {
    class Node {
        String s;
        double len;
        double repeat;
        public Node(String s, double len) {
            this.s = s;
            this.len = len;
            this.repeat = 1;
        }
    }

    private Deque stack = new ArrayDeque<>();

    public String decodeAtIndex(String S, int K) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);

            if (Character.isDigit(c)) {
                if (sb.length() > 0) {
                    Node node = new Node(sb.toString(), (stack.isEmpty() ? 0 : stack.peek().len) + sb.toString().length());
                    stack.push(node);
                    sb = new StringBuffer();
                }

                int num = Character.getNumericValue(c);
                stack.peek().repeat *= num;
                stack.peek().len *= num;

                continue;
            }

            if (Character.isAlphabetic(c)) {
                sb.append(c);
                continue;
            }

            System.out.println("出错了");
        }
        if (sb.length() > 0) {
            Node node = new Node(sb.toString(), (stack.isEmpty() ? 0 : stack.peek().len) + sb.toString().length());
            stack.push(node);
            sb = new StringBuffer();
        }

        K = K-1;

        while (true) {
            Node node = stack.pop();
            // 重复前字符串长度
            double len1 = node.len / node.repeat;
            // 当前str代表的位置,从0开始
            // [len1-node.s.length(), len1-1]

            // K round到[0, len1-1]直接
            if (K != 0) {
                K = K % (int)len1;
            }

            if (K >= len1-node.s.length() && K <= len1-1) {
                return node.s.charAt(K - (int)(len1-node.s.length())) + "";
            }
        }
    }
}
  • 错误1:len用int类型溢出;
  • 错误2:repeat用int类型溢出。
    880. Decoded String at Index, medium, stack_第1张图片

改进

速度比较慢,可以在len>=K时停止构建。没有用。

你可能感兴趣的:(leetcode题解)