题目
给你一个整数 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"。
题解
数据量级;
这么大数量级,上一步的选择决定了下一步的选择;按照我刷leetcode题的经验,这题大概率用动态规划。
想到动态规划就要考虑状态转移方程;
- 将'a', 'e', 'i', 'o', 'u'逐一放在数组中list = [[1,1,1,1,1]];
- 对于任意k位置的可能结果
- a结尾的数量list[k][0]=list[k−1][1]+list[k−1][2]+list[k−1][4]
- e结尾的数量list[k][1]=list[k−1][0]+list[k−1][2]
- i结尾的数量list[k][2]=list[k−1][1]+list[k−1][3]
- o结尾的数量list[k][3]=list[k−1][2]
- u结尾的数量list[k][4]=list[k−1][2]+list[k−1][3]
根据上述状态转移方程编辑代码如下
代码
var countVowelPermutation = function (n) {
const MOD = 1000000007
const list = []
for (let i = 0; i < n; i++) {
list[i] = Array(5).fill(0)
}
list[0] = Array(5).fill(1)
for (let i = 1; i < n; i++) {
list[i][0] = list[i - 1][0]
list[i][0] = list[i - 1][1]
list[i][1] = list[i - 1][0] + list[i - 1][2]
list[i][2] =
list[i - 1][0] + list[i - 1][1] + list[i - 1][3] + list[i - 1][4]
list[i][3] = list[i - 1][2] + list[i - 1][4]
list[i][4] = list[i - 1][0]
for (let j = 0; j < 5; j++) list[i][j] %= MOD
}
let result = 0
for (let i = 0; i < 5; i++) result += list[n - 1][i]
return result % MOD
}