IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 每日一题:【力扣552】学生出勤记录 II——hard -> 正文阅读

[数据结构与算法]每日一题:【力扣552】学生出勤记录 II——hard

前言

本文旨在记录与分享个人的刷题经验,因水平受限,观点难免偏颇,欢迎大家在评论区交流意见!

LeetCode 552. 学生出勤记录 II

可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:

  • 'A':Absent,缺勤
  • 'L':Late,迟到
  • 'P':Present,到场
    如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:

总出勤 计,学生缺勤(‘A’)严格 少于两天。
学生 不会 存在 连续 3 天或 连续 3 天以上的迟到(‘L’)记录。
给你一个整数 n,表示出勤记录的长度(次数)。请你返回记录长度为 n时,可能获得出勤奖励的记录情况 数量 。答案可能很大,所以返回对 10^9 + 7取余 的结果。

示例 1:

输入:n = 2
输出:8
解释:
有 8 种长度为 2 的记录将被视为可奖励:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" 
只有"AA"不会被视为可奖励,因为缺勤次数为 2 次(需要少于 2 次)。

示例 2:

输入:n = 1
输出:3

示例 3:

输入:n = 10101
输出:183236316

提示:
1 <= n <= 105


解法一:动态规划—— O ( n ) O(n) O(n)

思路——找到重复状态,写状态方程

分析:

  • 直接上动态规划!根据题意我们可以得到3种状态,细分为该位置是否以'A'结尾,写出位置在 i i i——能拿到奖励的情况——的总数——状态转移方程 d p [ i ] dp[i] dp[i]
    • ①以'A'结尾:
      -'A'只能出现一次,所以有 d p [ i ] = d p [ i ? 1 ] ? d p [ n ? i ] dp[i]=dp[i - 1]*dp[n - i] dp[i]=dp[i?1]?dp[n?i]'A'可以出现在任何地方,而情况总和'A'前的所有情况 × \times ×'A'后的所有情况
    • ②不以A结尾:
      • Ⅰ.以P结尾,可以为???P即任意情况,所以 d p [ i ] = d p [ i ? 1 ] dp[i] = dp[i - 1] dp[i]=dp[i?1]
      • Ⅱ 以L结尾,前面除了LL都可以,所以 d p [ i ] = d p [ i ? 1 ] ? d p [ i ? 4 ] dp[i] = dp[i - 1] - dp[i - 4] dp[i]=dp[i?1]?dp[i?4],为什么要减去 d p [ i ? 4 ] dp[i - 4] dp[i?4]呢?是因为以L结尾前面的情况不能像以P结尾一样,它是有限制的。那么限制是多少呢?我们只需要找到不符合条件的???PLLL这种情况,所以要从减去P前的情况,共为 d p [ i ? 4 ] dp[i - 4] dp[i?4]

步骤——设置初始状态值,再利用状态转移方程计算数量

  • ①设置模:根据题目要求,设置一个final long M = 1000000007;,用于取模
  • ②初始化状态值:因为我们有 d p [ i ] = d p [ i ? 1 ] ? d p [ i ? 4 ] dp[i] = dp[i - 1] - dp[i - 4] dp[i]=dp[i?1]?dp[i?4]这种情况,所以只有当i >= 4的时候才能利用状态转移方程,为此我们要定义dp[0]~dp[3]这四种情况的状态值
  • ③分情况计算数量,再合并:先计算不以A结尾,再利用得到的dp[n]计算以A结尾的情况,最终得到的是合并的结果
  • ④注意点
    • Ⅰ.dp的长度dp.length = Math.max(n+1,4);
    • Ⅱ.取模:每次计算均要取模,且为了防止负数取模取出正数,需要 ( M ? x ) m o d M (M-x) mod M (M?x)modM
    • Ⅲ.返回值:注意将long转为int

代码实现:

class Solution {
		//题目要求的取模
    final long M = 1000000007;
    public int checkRecord(int n) {
		//状态方程的最少需要长度为4的数组
        long[] dp = new long[n <= 3 ? 4 : n + 1];
		//先计算不含'A'的情况
        dp[0] = 1;//默认为1,
        dp[1] = 2;//长度为1,只有'P','L'2种情况
        dp[2] = 4;//长度为2,只有'PL','LP','PP','LL'4种情况
        dp[3] = 7;//长度为3,只有2*2*2 - 'LLL'= 7种情况
		//从i = 4开始可以利用状态方程
        for(int i = 4;i <= n;i ++){
       		//合并了不含'A'的状态方程
			//为了保证取余的同号,使用(M- X) % M
            dp[i] = (2* dp[i - 1] % M) + (M- dp[i -4]) % M;
        }
        long sum = dp[n];
		//现在开始计算包含'A'的情况
        for(int i = 1;i <= n;i ++){
            sum += (dp[i - 1] * dp[n - i]) % M;
        }
        return (int)(sum % M);
    }
}

复杂度分析: O ( n ) O(n) O(n) O ( n ) O(n) O(n)

  • 时间复杂度: O ( n ) O(n) O(n)——动态规划需要计算 n天的状态,每天的状态有3个,每天的状态需要 O ( 1 ) O(1) O(1)的时间计算。
  • 空间复杂度: O ( n ) O(n) O(n)——开辟了一个长度为 n + 1 n+1 n+1的数组

结尾

本题除了动态规划,还可以用矩阵来写,但是我还不会QAQ

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 12:18:53  更:2021-08-19 12:19:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 11:22:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码