每天一道算法题

LeetCode第38题:外观数列

给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:
1
11
21
1211
111221
第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

这道题一开始还以为只有11需要合并,写了一堆特殊判断,一运行发现只要是相同的都需要合并,于是删掉重写,代码反而干净多了。

/**
     * 直接递归即可
     */
    public static String countAndSay(int n) {
        if (n == 1) {
            return "1";
        }
        return say(countAndSay(--n));
    }

    /**
     * 转换的方法,引入两个变量记录下上个字符和出现的次数,出现不一致的时候拼接上就OK
     */
    private static String say(String str) {
        StringBuilder ans = new StringBuilder();
        char last = str.charAt(0);
        int num = 1;
        for (int i = 1; i < str.length(); i++) {
            if (str.charAt(i) != last) {
                ans.append(num).append(last);
                last = str.charAt(i);
                num = 1;
            } else {
                num++;
            }
        }
        // 循环结束后还要处理剩余的数值
        ans.append(num).append(last);
        return ans.toString();
    }

你可能感兴趣的:(每天一道算法题)