【力扣时间】【1220】【困难】统计元音字母序列的数目

星期一的困难,不止是不想上班……

1、看题

我是题

不要被困难吓倒,实际上这题并不多麻烦!

2、审题

题目倒是内容不多,不过还是有几点需要注意一下:

  1. 字符串仅能使用给出的5个元音字母
  2. 每个元音字母都有自己后续的限制
  3. 总数很大,需要对109+7取模

通常来说,遇到需要取模的大数结果,都意味有一定的难度。毕竟你需要考虑的情况和数量级有异常大的要求。

但这题真的很一般。

3、思路

首先明确一点,我们仅需要返回能够组成的不同字符串的数量
题目并不要求我们列出全部(毕竟这个数量级也不好列)。

而组成字符串的元素仅有5个元音字母,各个元音字母的后续都有各自的规则。
于是你会发现,这5个元音字母就组成了一个简单的状态机。

接着,我们再根据示例进行后续的分析。
n=1时,结果为5,即 “a”,“e”, “i” , “o” 和 “u"五个字母。
n=2时,结果为10,详细可以查看示例2。
分析结果后会发现,由于字母’a’的规则为每个元音 ‘a’ 后面都只能跟着 ‘e’,于是在n=2时, ‘a’ 的后续只能组成 “ae”。
同理,字母’e’的规则为每个元音 ‘e’ 后面只能跟着 ‘a’ 或者是 ‘i’,于是n=2时有"ea"和"ei”。

于是你会发现,每次延伸字符串的长度时,所有尾缀为’a’的字符串可以延伸出1个,'e’的可以延伸出2个。同理,'i’为4个,'o’为2个,'u’为1个。
以此我们就能知道每次延伸字符串时的数量变化

但是不行。
仅记录数量可不行,毕竟字符串还可能会继续延伸。我们得知道当字符串长度为n时,以"a", “e”, “i” , “o” 和 "u"结尾的字符串各有多少个,才能统计n+1时的数量。

再结合上面的规则就会发现:
f(a,n) = f(e,n-1) + f(i,n-1) + f(u,n-1)
同理,还可列出其他四个,如下:
f(e,n) = f(a,n-1) + f(i,n-1)
f(i,n) = f(e,n-1) + f(o,n-1)
f(o,n) = f(i,n-1)
f(u,n) = f(i,n-1) + f(o,n-1)

好吧,到这里方案已经呼之欲出了。

最后,记得还要取模哦。

4、开工!

class Solution {

    private static final int MOD = 1000000007;

    public int countVowelPermutation(int n) {
        //current[0~4]表示当前长度时最后一位a、e、i、o、u的数量
        long[] current = new long[]{1, 1, 1, 1, 1};
        long[] next;
        while (n > 1) {
            next = new long[5];

            next[0] = (current[1] + current[2] + current[4]) % MOD;
            next[1] = (current[0] + current[2]) % MOD;
            next[2] = (current[1] + current[3]) % MOD;
            next[3] = current[2] % MOD;
            next[4] = (current[2] + current[3]) % MOD;

            current = next;
            n--;
        }

        //计算总长度
        long sum = 0;
        for (int i = 0; i < 5; i++) {
            sum += current[i];
        }

        return (int) (sum % MOD);
    }
}

思路什么的应该很清晰了,后面就不再分析。

5、提交

在这里插入图片描述

6、咀嚼

嗯……
时间复杂度为O(CN),其中C=5
空间复杂度也为O(CN),毕竟我每次循环时都新建了一个长度为5的数组。

而实际上这部可以省略,仅使用到两个长度为5的数组就行,但代价是每次循环完后,要拷贝一次,会浪费些许时间。

7、康康大牛!

很明显,困难题加上不上不下的耗时排名,这题必有黑科技。
于是刷完后我也是光速冲到了题解里。

然后就看到了矩阵快速幂这么个东西。

相信各位在大学时都学过一个叫 《高等数学》 的课程。
而里面必然讲到过矩阵乘法这么个东西。
个人认为矩阵相关的内容相较其他高数内容来说还是十分简单的毕竟是少数连我都听懂了的 ,但奈何生活中实在很少应用到。于是乎,我又华丽丽地忘得一干二净了。

好吧,贴出三叶大佬的题解,供大家学习学习。

8、总结

今天的困难题属于较为简单的辣种了。
你会发现,我这种解法并不难想,更不难以实现。而这题锦上添花的矩阵快速幂做法也绝非什么高攀不起的做法,毕竟思路都是一致的,只是实现上有根本性的 区别。

但总之,能找个时间再好好回顾曾经学过的知识,还是挺不错的。
找个时间再回想一下被高数支配的恐惧

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值