【LeetCode每日一题】1220:统计元音字母序列的数目

196 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。

1220:统计元音字母序列的数目

题意

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

  • 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i', 'o', 'u')
  • 每个元音 'a' 后面都只能跟着 'e'
  • 每个元音 'e' 后面只能跟着 'a' 或者是 'i'
  • 每个元音 'i' 后面 不能 再跟着另一个 'i'
  • 每个元音 'o' 后面只能跟着 'i' 或者是 'u'
  • 每个元音 'u' 后面只能跟着 'a'

由于答案可能会很大,所以请你返回 模 10^9 + 7 之后的结果。

提示:

  • 1 <= n <= 2 * 10^4

示例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

题解:dp

通过题意可以知道:

  • 以a结尾的话前面只能是u,i,e
  • 以e结尾的话前面只能是a,i
  • 以i结尾的话前面只能是e,o
  • 以o结尾的话前面只能是i
  • 以u结尾的话前面只能是i,o

于是我们最终的结果可以视为:n个字符分别以a,e,i,o,u结尾的个数总和。

联想到dp,于是:前个字符其中以字符结尾能满足题意的字符串个数

个人习惯dp数组下标从1开始:于是j=1,2,3,4,5分别表示为a,e,i,o,u

于是状态转移方程为:

具体代码如下:

C++代码:

class Solution {
public:
    int dp[20010][6];
    int mod=1e9+7;
    int countVowelPermutation(int n) {
        int ans=0;
        for(int i=1;i<=5;i++) dp[1][i]=1;
        for(int i=2;i<=n;i++){
            dp[i][1]=((dp[i-1][2]+dp[i-1][3])%mod+dp[i-1][5])%mod;  //a结尾的话前面只能是u,i,e;后面同理
            dp[i][2]=(dp[i-1][1]+dp[i-1][3])%mod;
            dp[i][3]=(dp[i-1][2]+dp[i-1][4])%mod;
            dp[i][4]=dp[i-1][3]%mod;
            dp[i][5]=(dp[i-1][3]+dp[i-1][4])%mod;
        }
        for(int i=1;i<=5;i++) ans=(ans+dp[n][i])%mod;
        return ans;
    }
};

Java代码:

class Solution {
    public int countVowelPermutation(int n) {
        int dp[][]=new int[n+1][6];  //dp[i][j]:前i个字符其中以字符j结尾组成满足题意的个数
        int mod=(int)1e9+7;
        int ans=0;
        //初始化
        for(int i=1;i<=5;i++) dp[1][i]=1;
        for(int i=2;i<=n;i++){
            dp[i][1]=((dp[i-1][2]+dp[i-1][3])%mod+dp[i-1][5])%mod;  //a结尾的话前面只能是u,i,e;后面同理
            dp[i][2]=(dp[i-1][1]+dp[i-1][3])%mod;
            dp[i][3]=(dp[i-1][2]+dp[i-1][4])%mod;
            dp[i][4]=dp[i-1][3]%mod;
            dp[i][5]=(dp[i-1][3]+dp[i-1][4])%mod;
        }
        for(int i=1;i<=5;i++) ans=(ans+dp[n][i])%mod;
        return ans;
    }
}