552. Student Attendance Record II
/** * 552. Student Attendance Record II * https://leetcode.com/problems/student-attendance-record-ii/ * An attendance record for a student can be represented as a string where each character signifies whether the student was absent, late, or present on that day. * The record only contains the following three characters: 'A': Absent. 'L': Late. 'P': Present. Any student is eligible for an attendance award if they meet both of the following criteria: 1. The student was absent ('A') for strictly fewer than 2 days total. 2. The student was never late ('L') for 3 or more consecutive days. Given an integer n, return the number of possible attendance records of length n that make a student eligible for an attendance award. The answer may be very large, so return it modulo 10^9 + 7. Example 1: Input: n = 2 Output: 8 Explanation: There are 8 records with length 2 that are eligible for an award: "PP", "AP", "PA", "LP", "PL", "AL", "LA", "LL" Only "AA" is not eligible because there are 2 absences (there need to be fewer than 2). Example 2: Input: n = 1 Output: 3 Example 3: Input: n = 10101 Output: 183236316 Constraints: 1 <= n <= 10^5 */ /** * Solution: DFS + Memorizaion, use unordered_map for cache will LTE, pass all test by cache by vector; * Time complexity: O(3n) * Space complexity: O(n) */ #include <iostream> #include <string> #include <unordered_map> #include <vector> using namespace std; class Solution { private: vector<vector<vector<int>>> cache; // unordered_map<string, int> cache; public: const static int MOD = 1e9 + 7; /*string getKey(int current_level, int absent_count, int late_count) { return std::to_string(current_level) + "," + std::to_string(absent_count) + "," + std::to_string(late_count); }*/ int checkRecord(int n) { initCache(n); int result = dfs(0, n, 0, 0); return result; } /** * init cache: HEIGHT, WIDTH, DEPTH; * HEIGHT: represent two triteria; * WIDTH: represent 3 chars: A,L,P; * DEPTH: for n; * */ void initCache(int n) { int HEIGHT = 2, WIDTH = 3, DEPTH = n; cache.resize(HEIGHT); for (int i = 0; i < HEIGHT; i++) { cache[i].resize(WIDTH); for (int j = 0; j < WIDTH; j++) { cache[i][j].resize(DEPTH); } } for (int i = 0; i < HEIGHT; i++) { cache[i].resize(WIDTH); for (int j = 0; j < WIDTH; j++) { for (int k = 0; k < DEPTH; k++) { cache[i][j][k] = -1; } } } } int dfs(int current_level, int n, int absent_count, int late_count) { if (absent_count == 2 || late_count == 3) { return 0; } if (current_level == n) { return 1; } // LTE by unordered_map /*string key = getKey(current_level, absent_count, late_count); if (cache.find(key) != cache.end()) { return cache[key]; }*/ if (cache[absent_count][late_count][current_level] != -1) { return cache[absent_count][late_count][current_level]; } int current_result = 0; // add another absent count current_result += dfs(current_level + 1, n, absent_count + 1, 0); current_result %= MOD; // add another late count current_result += dfs(current_level + 1, n, absent_count, late_count + 1); current_result %= MOD; // add another present count current_result += dfs(current_level + 1, n, absent_count, 0); current_result %= MOD; // cache[key] = current_result; cache[absent_count][late_count][current_level] = current_result; return current_result; } };