学生出勤记录 II

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/student-attendance-record-ii

题目描述:

可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:
'A':Absent,缺勤
'L':Late,迟到
'P':Present,到场
如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:
按 总出勤 计,学生缺勤('A')严格 少于两天。
学生 不会 存在 连续 3 天或 连续 3 天以上的迟到('L')记录。
给你一个整数 n ,表示出勤记录的长度(次数)。请你返回记录长度为 n 时,可能获得出勤奖励的记录情况 数量 。答案可能很大,所以返回对 109 + 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

题目分析:
  • 总共的A不能超过2次:A出现0次和1次。
  • 连续的L不能超过3次:连续L出现次数0次,1次,2次。
思路一:

直接深度遍历(超时)

class Solution {
    public int mod = (int) 1e9+7;
    public int count;
    public int checkRecord(int n) {
        count = n;
        int result = dfs(0, 0, 0);
        return result;
    }
    public int dfs(int num, int absent, int late) {
        if (num == count) return 1;

        int result = 0;
        result += dfs(num + 1, absent, 0);
        if (absent < 1) { // 缺勤最多1次
            result += dfs(num + 1, 1, 0);
        }
        if (late < 2) { // 连续迟到最多2次
            result += dfs(num + 1, absent, late + 1);
        }
        result = result % mod;
        return result;
    }
}
思路二:

观察暴力dfs可以发现,有很多场景进行了重复递归,可以使用记忆化搜索进行优化.

class Solution {
    public int mod = (int) 1e9+7;
    public int count;
    public int[][][] arr;
    public int checkRecord(int n) {
        count = n;
        arr = new int[n][2][3];
        int result = dfs(0, 0, 0);
        return result;
    }
    public int dfs(int num, int absent, int late) {
        if (num == count) return 1;
        if (arr[num][absent][late] != 0) return arr[num][absent][late]; // 对于相同num,absent,late的情况,减枝。
        int result = 0;
        result += dfs(num + 1, absent, 0);
        result %= mod;
        if (absent < 1) { // 缺勤最多1次
            result += dfs(num + 1, 1, 0);
            result %= mod;
        }
        if (late < 2) { // 连续迟到最多2次
            result += dfs(num + 1, absent, late + 1);
            result %= mod;
        }
   
        arr[num][absent][late] = result; // 记录num,absent,late情况时的数量,用于减枝。
        return result;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容