LeetCode 551: Student Attendance Record I (Single Pass Absence + Late Streak Check)
LeetCode 551StringSimulationToday we solve LeetCode 551 - Student Attendance Record I.
Source: https://leetcode.com/problems/student-attendance-record-i/
English
Problem Summary
Given a string s representing attendance records ('A', 'L', 'P'), return true if the student can get an attendance award. The student is disqualified if there are at least two 'A' characters or if there are three consecutive 'L' characters.
Key Insight
We only need two running states while scanning once: total number of absences and current consecutive late streak. Any time either rule is violated, we can return immediately.
Algorithm
- Initialize absent = 0, lateStreak = 0.
- For each character in s:
• if 'A', increment absent, reset lateStreak to 0.
• if 'L', increment lateStreak.
• if 'P', reset lateStreak to 0.
- If absent >= 2 or lateStreak >= 3, return false.
- If scan finishes, return true.
Complexity Analysis
Let n be the length of s.
Time: O(n).
Space: O(1).
Common Pitfalls
- Forgetting to reset lateStreak on 'A' and 'P'.
- Counting total 'L' instead of consecutive 'L'.
- Using strict > checks instead of >= for the disqualifying thresholds.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean checkRecord(String s) {
int absent = 0;
int lateStreak = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == 'A') {
absent++;
lateStreak = 0;
} else if (c == 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
}
}func checkRecord(s string) bool {
absent := 0
lateStreak := 0
for _, ch := range s {
if ch == 'A' {
absent++
lateStreak = 0
} else if ch == 'L' {
lateStreak++
} else {
lateStreak = 0
}
if absent >= 2 || lateStreak >= 3 {
return false
}
}
return true
}class Solution {
public:
bool checkRecord(string s) {
int absent = 0;
int lateStreak = 0;
for (char c : s) {
if (c == 'A') {
absent++;
lateStreak = 0;
} else if (c == 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
}
};class Solution:
def checkRecord(self, s: str) -> bool:
absent = 0
late_streak = 0
for ch in s:
if ch == 'A':
absent += 1
late_streak = 0
elif ch == 'L':
late_streak += 1
else:
late_streak = 0
if absent >= 2 or late_streak >= 3:
return False
return Truevar checkRecord = function(s) {
let absent = 0;
let lateStreak = 0;
for (const ch of s) {
if (ch === 'A') {
absent++;
lateStreak = 0;
} else if (ch === 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
};中文
题目概述
给定出勤字符串 s(只包含 'A'、'L'、'P'),判断该学生是否可获得出勤奖励。若 'A' 至少出现 2 次,或出现连续 3 次 'L',则不满足条件。
核心思路
一次遍历就够:维护“缺勤总数”和“当前连续迟到次数”两个状态。任一状态触发阈值,立即返回 false。
算法步骤
- 初始化 absent = 0,lateStreak = 0。
- 逐字符扫描:
• 遇到 'A':absent++,并将 lateStreak 清零。
• 遇到 'L':lateStreak++。
• 遇到 'P':lateStreak 清零。
- 若 absent >= 2 或 lateStreak >= 3,直接返回 false。
- 扫描结束仍未违规,返回 true。
复杂度分析
设字符串长度为 n。
时间复杂度:O(n)。
空间复杂度:O(1)。
常见陷阱
- 忘记在 'A' 或 'P' 时重置连续迟到计数。
- 错把“连续 3 次迟到”写成“总共 3 次迟到”。
- 判断条件误写为 > 而不是 >=。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean checkRecord(String s) {
int absent = 0;
int lateStreak = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == 'A') {
absent++;
lateStreak = 0;
} else if (c == 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
}
}func checkRecord(s string) bool {
absent := 0
lateStreak := 0
for _, ch := range s {
if ch == 'A' {
absent++
lateStreak = 0
} else if ch == 'L' {
lateStreak++
} else {
lateStreak = 0
}
if absent >= 2 || lateStreak >= 3 {
return false
}
}
return true
}class Solution {
public:
bool checkRecord(string s) {
int absent = 0;
int lateStreak = 0;
for (char c : s) {
if (c == 'A') {
absent++;
lateStreak = 0;
} else if (c == 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
}
};class Solution:
def checkRecord(self, s: str) -> bool:
absent = 0
late_streak = 0
for ch in s:
if ch == 'A':
absent += 1
late_streak = 0
elif ch == 'L':
late_streak += 1
else:
late_streak = 0
if absent >= 2 or late_streak >= 3:
return False
return Truevar checkRecord = function(s) {
let absent = 0;
let lateStreak = 0;
for (const ch of s) {
if (ch === 'A') {
absent++;
lateStreak = 0;
} else if (ch === 'L') {
lateStreak++;
} else {
lateStreak = 0;
}
if (absent >= 2 || lateStreak >= 3) {
return false;
}
}
return true;
};
Comments