[leetcode 周赛 157] 1220 统计元音字母序列的数目

1220 Count Vowels Permutation 统计元音字母序列的数目

问题描述

给你一个整数 n,请你帮忙统计一下我们可以按下述规则形成多少个长度为 n 的字符串:

  • 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i', 'o', 'u'

    • 每个元音 'a' 后面都只能跟着 'e'
    • 每个元音 'e' 后面只能跟着 'a' 或者是 'i'
    • 每个元音 'i' 后面 不能 再跟着另一个 'i'
    • 每个元音 'o' 后面只能跟着 'i' 或者是 'u'
    • 每个元音 'u' 后面只能跟着 'a'
      由于答案可能会很大,所以请你返回 模 10^9 + 7 之后的结果。
  • 示例 1:

输入:n = 1
输出:5
解释:所有可能的字符串分别是:"a", "e", "i" , "o" 和 "u"。

  • 示例 2:

输入:n = 2
输出:10
解释:所有可能的字符串分别是:"ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" 和 "ua"。

  • 示例 3:

输入:n = 5
输出:68

-提示:
- 1 <= n <= 2 * 10^4

思路

  • 读题
    根据题目所给字母组合的规则, 组合出字符串

寻找规律

寻找规律

代码实现

寻找规律 动态规划

class Solution {
    // 注意 此处必须使用long类型来存储 不然MOD结果出错...
    private static long[][] dp = new long[20050][5];
    // m 5个字母
    // size 输入值n的规模
    private static int m = 5, size = 20050;
    // 取模数 10^9 + 7
    private final static int MOD = (int)Math.pow(10, 9)+7;

    // 提前加载
    static {
        // 初始化 第一轮全为1
        for (int i = 0; i < 5; i++) {
            dp[0][i] = 1;
        }
        
        // a e i o u
        int a = 0, e = 1, i = 2, o = 3, u = 4;
        for (int i1 = 1; i1 < size; i1++) {
            // [a] = e+i+u
            dp[i1][a] = (dp[i1 - 1][e] + dp[i1 - 1][i] + dp[i1 - 1][u]) % MOD;
            // [e] = a+i
            dp[i1][e] = (dp[i1 - 1][a] + dp[i1 - 1][i]) % MOD;
            // [i] = e+o
            dp[i1][i] = (dp[i1 - 1][e] + dp[i1 - 1][o]) % MOD;
            // [o] = i
            dp[i1][o] = dp[i1 - 1][i];
            // [u] = i+o
            dp[i1][u] = (dp[i1 - 1][i] + dp[i1 - 1][o]) % MOD;
        }
    }

    public int countVowelPermutation(int n) {
        if (n < 0 || n > size) {
            return -1;
        }

        int res = 0;
        for (int i = 0; i < m; i++) {
            res += dp[n-1][i];
            res %= MOD;
        }
        return res;
    }
}

参考资源

第 157 场周赛 全球排名
【算法实况】体验使用 iPadOS 打算法竞赛 - 力扣周赛 - LeetCode Weekly 157

posted @ 2019-10-12 22:22  slowbird  阅读(353)  评论(0编辑  收藏  举报