38. Count and Say

只要理解了题意,其实挺简单的。比如"11113222"读做“4个1,1个3,3个2”,下一个数字就是"411332"。正好最近看到某个解谜游戏中也有个类似的密码,感觉挺巧合的。。。

public class Solution {

    public String countAndSay(int n) {
        if (n <= 1)
            return "1";

        // 循环n-1次
        String init = "1";
        for (int i = 2; i <= n; i++) {
            StringBuilder sb = new StringBuilder();
            char lastChar = 0;
            int count = 0;
            // 其实就是计算一个字符会连续出现几次
            for (int j = 0; j < init.length(); j++) {
                char thisChar = init.charAt(j);
                if (count == 0 || thisChar != lastChar) {
                    if (count != 0) {
                        sb.append(count);
                        sb.append(lastChar);
                    }
                    lastChar = thisChar;
                    count = 1;
                } else if (thisChar == lastChar) {
                    count++;
                }
            }
            // 别忘了最后的这个字符
            if (count != 0) {
                sb.append(count);
                sb.append(lastChar);
            }

            init = sb.toString();
        }

        return init;
    }
}

解法还是很简单的。而且这个解法可以beat 64.4%。但我突发奇想,如果先计算n=10,再计算n=20,肯定会有很多重复计算,是否可以加个缓存?把每次计算结果缓存起来,如果命中缓存就不用计算了。于是:

public class Solution {
    // 作弊。。。全局的缓存
    private static Map<Integer, String> sayCache = new HashMap<Integer, String>();

    public String countAndSay(int n) {
        if (sayCache.containsKey(n))
            return sayCache.get(n);
        if (n <= 1)
            return "1";

        // 循环n-1次
        String init = "1";
        for (int i = 2; i <= n; i++) {
            // 先查看缓存,命中了就不用重复计算了
            if (sayCache.containsKey(i)) {
                init = sayCache.get(i);
                continue;
            }
            StringBuilder sb = new StringBuilder();
            char lastChar = 0;
            int count = 0;
            for (int j = 0; j < init.length(); j++) {
                char thisChar = init.charAt(j);
                if (count == 0 || thisChar != lastChar) {
                    if (count != 0) {
                        sb.append(count);
                        sb.append(lastChar);
                    }
                    lastChar = thisChar;
                    count = 1;
                } else if (thisChar == lastChar) {
                    count++;
                }
            }

            if (count != 0) {
                sb.append(count);
                sb.append(lastChar);
            }

            init = sb.toString();
            // 更新缓存
            sayCache.put(i, init);
        }

        return init;
    }
}

这个解法也只能beat 64.4%,几乎没什么区别。因为leetcode的test case太少了,只有18个。如果数据量变大,有缓存的版本性能应该会好很多。

results matching ""

    No results matching ""