题目链接
Leetcode.1220 统计元音字母序列的数目 Rating : 1730
题目描述
给你一个整数 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 ∗ 1 0 4 1 <= n <= 2 * 10^4 1<=n<=2∗104
分析:线性dp
按照题目的要求,合法的组合如下:
- 结尾是
a
的,ea , ua , ia
- 结尾是
e
的,ae , ie
- 结尾是
i
的,ei , oi
- 结尾是
o
的,io
- 结尾是
u
的·,iu , ou
我们定义
f
(
i
,
j
)
f(i,j)
f(i,j) 为第 j
个字符为 a , e , i , o , u
的方案数,
f
(
1
,
j
)
f(1,j)
f(1,j) 就是第 j
个字符为 a
的方案数。
按照定义,答案为 a n s = ( f ( 1 , n ) + f ( 2 , n ) + f ( 3 , n ) + f ( 4 , n ) + f ( 5 , n ) ) m o d M O D ans = (f(1,n)+f(2,n)+f(3,n)+f(4,n) + f(5,n)) mod MOD ans=(f(1,n)+f(2,n)+f(3,n)+f(4,n)+f(5,n))modMOD
时间复杂度: O ( n ) O(n) O(n)
C++代码:
const int MOD = 1e9 + 7;
using LL = long long;
class Solution {
public:
int countVowelPermutation(int n) {
LL f[6][n+1];
memset(f,0,sizeof f);
for(int i = 1;i <= 5;i++) f[i][1] = 1;
for(int i = 2;i <= n;i++){
//ea , ia , ua
f[1][i] = (f[2][i-1] + f[3][i-1] + f[5][i-1]) % MOD;
//ae , ie
f[2][i] = (f[1][i-1] + f[3][i-1]) % MOD;
//ei , oi
f[3][i] = (f[2][i-1] + f[4][i-1]) % MOD;
//io
f[4][i] = (f[3][i-1]) % MOD;
//iu , ou
f[5][i] = (f[3][i-1] + f[4][i-1]) % MOD;
}
LL ans = 0;
for(int i = 1;i <= 5;i++) ans = (ans + f[i][n]) % MOD;
return ans;
}
};
Java代码:
class Solution {
private final int MOD = 1000_000_007;
public int countVowelPermutation(int n) {
long[][] f = new long[6][n + 1];
for(int i = 1;i <= 5;i++) f[i][1] = 1;
//1->a 2->e 3->i 4->o 5->u
for(int i = 2;i <= n;i++){
//ea , ia , ua
f[1][i] = (f[2][i-1] + f[3][i-1] + f[5][i-1]) % MOD;
//ae , ie
f[2][i] = (f[1][i-1] + f[3][i-1]) % MOD;
//ei , oi
f[3][i] = (f[2][i-1] + f[4][i-1]) % MOD;
//io
f[4][i] = (f[3][i-1]) % MOD;
//iu , ou
f[5][i] = (f[3][i-1] + f[4][i-1]) % MOD;
}
long ans = 0;
for(int i = 1;i <= 5;i++) ans = (ans + f[i][n]) % MOD;
return (int)ans;
}
}