【Leetcode】552. 学生出勤记录 II
552. 学生出勤记录 II
- 题目描述
- 解题思路
题目描述
可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:
- ‘A’:Absent,缺勤
- ‘L’:Late,迟到
- ‘P’:Present,到场
如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:
- 按 总出勤 计,学生缺勤(‘A’)严格 少于两天。
- 学生 不会 存在 连续 3 天或 连续 3 天以上的迟到(‘L’)记录。
给你一个整数 n ,表示出勤记录的长度(次数)。请你返回记录长度为 n 时,可能获得出勤奖励的记录情况 数量 。答案可能很大,所以返回对 109 + 7 取余 的结果。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/student-attendance-record-ii
示例1
输入:n = 2
输出:8
解释:
有 8 种长度为 2 的记录将被视为可奖励:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL"
只有"AA"不会被视为可奖励,因为缺勤次数为 2 次(需要少于 2 次)。
示例2
输入:n = 1
输出:3
提示
- 1 < = n < = 1 0 5 1 <= n <= 10^5 1<=n<=105
解题思路
本题考虑使用动态规划
解决。由于可奖励的出勤记录要求是:缺勤次数少于 2 和连续迟到次数少于 3,因此动态规划的状态由总天数、缺勤次数和结尾连续迟到次数决定(由于不会记录连续迟到次数等于或多于 3 的情况,因此非结尾的连续迟到次数一定少于 3,只需要记录结尾连续迟到次数即可)。
定义 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示前i天由j个‘A’且结尾有连续k个‘L’的可奖励的出勤记录的数量。其中 0 < = i < = n , 0 < = j < = 1 , 0 < = k < = 2 0<=i<=n, 0<=j<=1, 0<=k<=2 0<=i<=n,0<=j<=1,0<=k<=2。
当 i = 0 i=0 i=0时,没有任何出勤记录,此时“A”的数量和结尾连续“L”的数量一定为0,因此动态规划的边界情况是 d p [ 0 ] [ 0 ] [ 0 ] = 1 dp[0][0][0]=1 dp[0][0][0]=1。
当 1 < = i < = n 1<=i<=n 1<=i<=n时, d p [ i ] [ ] [ ] dp[i][][] dp[i][][]的值从 d p [ i − 1 ] [ ] [ ] dp[i-1][][] dp[i−1][][]的值转移得到,计算每个状态的值需要考虑第i天的出勤记录:
- 如果第i天的出勤记录是“P”,则前i天和前 i − 1 i-1 i−1天的出勤记录相比,“A”的数量不变,结尾连续“L”的数量清零,因此对 0 < = j < = 1 0<=j<=1 0<=j<=1,有 d p [ i ] [ j ] [ 0 ] : = d p [ i ] [ j ] [ 0 ] + ∑ k = 0 2 d p [ i − 1 ] [ j ] [ k ] dp[i][j][0]:= dp[i][j][0]+\sum^{2}_{k=0} {dp[i-1][j][k]} dp[i][j][0]:=dp[i][j][0]+k=0∑2dp[i−1][j][k]
- 如果第i天的出勤记录是"A",则前i天和前i-1天的出勤记录相比,“A"的数量加1,结尾连续"L"的数量清零,此时要求前i-1天的出勤记录中"A"的数量必须是0,否则前i天的出勤记录至少有两个"A”,不满足可奖励的条件,因此有: d p [ i ] [ 1 ] [ 0 ] : = d p [ i ] [ 1 ] [ 0 ] + ∑ k = 0 2 d p [ i − 1 ] [ 0 ] [ k ] dp[i][1][0]:=dp[i][1][0]+\sum^{2}_{k=0} {dp[i-1][0][k]} dp[i][1][0]:=dp[i][1][0]+k=0∑2dp[i−1][0][k]
- 如果第i天的出勤记录是"L",则前i天和前i-1天的出勤记录相比,”A“的数量不变,结尾连续”L”的数量加1,此时要求前i-1天的出勤记录中的结尾连续"L"的数量不超过1,否则前i天的出勤记录的结尾至少有3个“L”,不满足可奖励条件,因此对 0 < = j < = 1 0<=j<=1 0<=j<=1和 1 < = k < = 2 1<=k<=2 1<=k<=2,有: d p [ i ] [ j ] [ k ] : = d p [ i ] [ j ] [ k ] + d p [ i − 1 ] [ j ] [ k − 1 ] dp[i][j][k]:=dp[i][j][k]+dp[i-1][j][k-1] dp[i][j][k]:=dp[i][j][k]+dp[i−1][j][k−1]
上述状态转移方程对于i=1也适用
计算长度为n的所有可奖励的出勤记录的数量,即为计算 d p [ n ] [ ] [ ] dp[n][][] dp[n][][]的所有元素之和。计算过程中需要将结果对 1 0 9 + 7 10^9+7 109+7取模。
根据上述思路,可以得到时间复杂度和空间复杂度都是O(N)的实现,代码如下:
# -*- coding: utf-8 -*-## -------------------------------------------------------------------------------
# Name: 552. 学生出勤记录 II
# Description:
# Author: PANG
# Date: 2021/8/19
# -------------------------------------------------------------------------------
class Solution:def checkRecord(self, n: int) -> int:MOD = 10 ** 9 + 7# A 的数量,结尾连续 L 的数量dp = [[0, 0, 0], [0, 0, 0]]dp[0][0] = 1for i in range(1, n + 1):dpNew = [[0, 0, 0], [0, 0, 0]]# 以 P 结尾的数量for j in range(0, 2):for k in range(0, 3):dpNew[j][0] = (dpNew[j][0] + dp[j][k]) % MOD# 以 A 结尾的数量for k in range(0, 3):dpNew[1][0] = (dpNew[1][0] + dp[0][k]) % MOD# 以 L 结尾的数量for j in range(0, 2):for k in range(1, 3):dpNew[j][k] = (dpNew[j][k] + dp[j][k - 1]) % MODdp = dpNewtotal = 0for j in range(0, 2):for k in range(0, 3):total += dp[j][k]return total % MODif __name__ == '__main__':n = int(input())solution = Solution()print(solution.checkRecord(n))
【Leetcode】552. 学生出勤记录 II相关推荐
- LeetCode——552. 学生出勤记录 II(Student Attendance Record II)[困难]——分析及代码(Java)
LeetCode--552. 学生出勤记录 II[Student Attendance Record II][困难]--分析及代码[Java] 一.题目 二.分析及代码 1. 动态规划 (1)思路 ( ...
- leetcode: 552. 学生出勤记录 II
552. 学生出勤记录 II 来源:力扣(LeetCode) 链接: https://leetcode.cn/problems/student-attendance-record-ii/ 可以用字符串 ...
- LeetCode 552. 学生出勤记录 II(动态规划)
文章目录 1. 题目 2. 解题 1. 题目 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 10^9 + 7的值. 学生出勤记录是只 ...
- 552. 学生出勤记录 II
552. 学生出勤记录 II 可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 'L':Late,迟到 ...
- 力扣 -- 551. 学生出勤记录 I 、 552. 学生出勤记录 II
目录 551. 学生出勤记录 一 .题目描述 二. 实现思路以及代码 552. 学生出勤记录 II 一 .题目描述 二. 实现思路以及代码 551. 学生出勤记录 一 .题目描述 给你一个字符串 s ...
- Leetcode 552.学生出勤记录‖ 动态规划+容斥
题目链接:传送门 可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 'L':Late,迟到 'P':P ...
- C++Python描述 LeetCode 551. 学生出勤记录 I
C++&Python描述 LeetCode 551. 学生出勤记录 I 大家好,我是亓官劼(qí guān jié ),在公众号.CSDN.GitHub.B站.华为开发者论坛等平台分享一些 ...
- Java实现 LeetCode 551 学生出勤记录 I(暴力大法好)
551. 学生出勤记录 I 给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个 ...
- Leetcode每日一题-学生出勤记录 II(Student Attendance Record II)
可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 'L':Late,迟到 'P':Present,到场 ...
最新文章
- C#快速整理代码格式
- pip安装mysql-python失败,并显示EnvironmentError:找不到mysql_config
- 【Java Web开发指南】Spring一些基础问题整理
- iOS开发-ViewController的生命周期和切换
- 开工啦,开工啦,2022开工了
- AWS实例上AMI和用户名的映射表
- 自己写的android apk反编译,获取Android自己写好了的apk以及反编译
- 华为再发行30亿元超短期融资券
- SAP 设置或取消仓库不参与MRP运算(转)
- SolrCloud集群的安装使用以及Zookeeper的介绍
- 剑指|| offer1整数除法
- Message、Handler、Message Queue、Looper、Thread之间的关系(未完成)
- Html5的测试总结
- [转] android自定义布局中的平滑移动
- 升级LINUX内核(支持8G内存)的命令
- mysql 批量插入(记录帖)
- 《Unity 3D人工智能编程》——2.2 子弹类
- c语言程序书写遵循的规则,C程序书写时应遵循的规则
- vscode中使用md文件
- 计算机原理及应用自测题4,自测题-微计算机原理-电子发烧友网站