外观数列

167 阅读2分钟

这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

leetcode 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

示例 1:

输入: n = 1
输出: "1"
解释: 这是一个基本样例。

解题: 根据题目意思,这个外观数列其实就是统计这个字符串中相同字符的个数的一个字符串数,有countAndSay(1) = "1",countAndSay(n) 是对 countAndSay(n-1) 的描述。

所以`countAndSay(2)` 是描述`countAndSay(1)`的那个字符串"1":有一个1,就记作"11"。
而`countAndSay(3)` 是描述`countAndSay(2)`的那个字符串"11":有二个1,就记作"21"。
再有`countAndSay(4)` 是描述`countAndSay(3)`的那个字符串"21":有一个2、有一个1,就记作"1211"。
以此类推。。。。

既然给定有countAndSay(1) = "1",那么求countAndSay(n)就得先求得countAndSay(n-1),所以可以定义一个str代表前一个字符串描述,需要递归获取的,首先得判断如果n=1时直接返回字符串1,然后再针对递归获取的str字符串解析描述,定义一个count代表每一个数重复的数量,默认为1只有一个,然后循环遍历str的每一个字符,如果str有相同字符也会是相邻的,所以可以直接遍历,当str的第一个字符等于其后一个字符的时候,就将count+1,说明有多一个字符出现,一直统计当前这个字符有多少个相同的,直到有不同的字符出现,那么就这个描述从左到右拼接一个字符串[重复的数量+重复的数],注意count还需要重置为0,然后继续查询遍历下一个字符,最后将str和描述的字符串拼接返回即可。

class Solution {
    public String countAndSay(int n) {
        if (n == 1) {
            return "1";
        }
        String str = countAndSay(n - 1);
        StringBuilder builder = new StringBuilder();
        int count = 1;
        for (int i = 1; i < str.length(); i++) {
            if (str.charAt(i) == str.charAt(i - 1)) {
                count++;
                continue;
            }
            builder.append(count).append(str.charAt(i - 1));
            count = 1;
        }
        return builder.append(count).append(str.charAt(str.length() - 1)).toString();
    }
}

或者:根据题目1 <= n <= 30,那么可以针对这有限的几个数都枚举出来,先都生成countAndSay 1-30 的字符,放到哈希表,当查询的时候直接返回对于的字符就可以了。