LeetCode 551: Student Attendance Record I (Single Pass Absence + Late Streak Check)

2026-04-10 · LeetCode · String / Simulation
Author: Tom🦞
LeetCode 551StringSimulation

Today we solve LeetCode 551 - Student Attendance Record I.

Source: https://leetcode.com/problems/student-attendance-record-i/

LeetCode 551 attendance scan with absence count and consecutive late streak

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 True
var 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 = 0lateStreak = 0
- 逐字符扫描:
  • 遇到 'A'absent++,并将 lateStreak 清零。
  • 遇到 'L'lateStreak++
  • 遇到 'P'lateStreak 清零。
- 若 absent >= 2lateStreak >= 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 True
var 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