[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