leetcode-552. 学生出勤记录 II

题目

给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量。 答案可能非常大,你只需返回结果mod 10^9 + 7的值。

学生出勤记录是只包含以下三个字符的字符串:

'A' : Absent,缺勤
'L' : Late,迟到
'P' : Present,到场

如果记录不包含多于一个’A’(缺勤)或超过两个连续的’L’(迟到),则该记录被视为可奖励的。

示例 1:

输入: n = 2
输出: 8 
解释:
有8个长度为2的记录将被视为可奖励:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL"
只有"AA"不会被视为可奖励,因为缺勤次数超过一次。

注意:n 的值不会超过100000。

解题思路

动态规划,状态转移。参考题解做出来的。
对于字符串,其实需要考虑2点:
1.当前字符串是否包含A,2.当前字符串的末两位字符是什么。

这2个条件决定了结果的数量,分别讨论:

  1. 当前字符串已包含A:
    1.1 末尾不为L:可加P(下一步转到1.1)、可加L(下一步转到1.2)
    1.2 末尾为L,倒数第2位不为L:可加P(下一步转到1.1)、可加L(下一步转到1.3)
    1.3 末尾为L,倒数第2位也是L:可加P(下一步转到1.1)
  2. 当前字符串不包含A:
    2.1 末尾不为L:可加P(下一步转到2.1)、可加L(下一步转到2.2)、可加A(下一步转到1.1)
    2.2 末尾为L,倒数第2位不为L:可加P(下一步转到2.1)、可加L(下一步转到2.3)、可加A(下一步转到1.1)
    2.3 末尾为L,倒数第2位也是L:可加P(下一步转到2.1)、可加A(下一步转到1.1)

用a,b,c,d,e,f分别代表以上6个状态,则状态a(即上述1.1)共有6个状态来源:a+b+c+d+e+f(上述1.1、1.2、1.3、2.1、2.2、2.3均可以转到1.1),状态b(即上述1.2)共有1个状态来源(上述1.1可以转到1.1),以此类推,可以得到递推公式为:

a = a + b + c + d + e + f
b = a
c = b
d = d + e + f
e = d
f = e

初始状态:

a = 1	# 当前字符为A
b = 0	# 当前字符为A?L,对于1个字符来说不存在,所以为0
c = 0	# 当前字符为ALL,同上
d = 1	# 当前字符为P
e = 1	# 当前字符为L
f = 0		# 当前字符为LL,同上,不存在

成绩

时间>65.45%
空间>62.50%

代码

class Solution(object):
    def checkRecord(self, n):
        """
        :type n: int
        :rtype: int
        """
        base = 1000000007
        a,b,c,d,e,f = 1,0,0,1,1,0
        while n > 1:
            a,b,c,d,e,f = (a+b+c+d+e+f)%base, a, b, (d+e+f)%base, d, e
            n -= 1
        return (a+b+c+d+e+f) % base
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值