Skip to content
← All posts

Student Attendance Record I: Single-Pass String Check

5 min read
leetcodeproblemeasystrings

LeetCode 551, Student Attendance Record I, asks you to determine whether a student qualifies for an attendance award based on their record string. Each character is either 'A' (absent), 'L' (late), or 'P' (present). The eligibility rules are simple, but they require you to track two different conditions simultaneously as you scan the string. This makes it a great exercise in maintaining multiple pieces of state in a single pass.

The problem

A student's attendance record is a string of characters where each character is one of 'A', 'L', or 'P'. The student is eligible for an attendance award if both of these conditions are met:

  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 a string s, return True if the student is eligible, or False otherwise.

For example, "PPALLP" returns True because there is only 1 absence and only 2 consecutive lates. But "PPALLL" returns False because there are 3 consecutive lates.

Attendance record: "PPALLP"012345PPALLP1 absence2 consecutive L'sPresent (P)Absent (A)Late (L)
A student is eligible if they have strictly fewer than 2 A's and never 3 or more consecutive L's. This record ("PPALLP") has 1 absence and at most 2 consecutive lates, so the student is eligible.

The approach

You can solve this in a single pass through the string. Keep two counters:

  • absent_count: how many 'A' characters you have seen so far.
  • consec_late: how many consecutive 'L' characters you have seen ending at the current position.

As you scan each character, update these counters. If the character is 'A', increment absent_count. If the character is 'L', increment consec_late. For anything else (including 'A'), reset consec_late to 0. At any point, if absent_count reaches 2 or consec_late reaches 3, you can immediately return False.

The consecutive late counter must reset whenever you see a non-'L' character. An 'A' in the middle of lates breaks the streak, so "LALL" has at most 1 consecutive late at any point after the 'A'.

The solution

def checkRecord(s):
    absent_count = 0
    consec_late = 0
    for ch in s:
        if ch == 'A':
            absent_count += 1
            consec_late = 0
            if absent_count >= 2:
                return False
        elif ch == 'L':
            consec_late += 1
            if consec_late >= 3:
                return False
        else:
            consec_late = 0
    return True

Here is how each piece works:

  • Absent check. When you see 'A', increment the absent counter and reset the consecutive late streak. If absences hit 2, return False immediately.
  • Late check. When you see 'L', increment the consecutive late counter. If it reaches 3, return False immediately.
  • Present (or any other character). Reset the consecutive late counter to 0. The absent counter stays the same.
  • Default return. If you finish scanning without either condition triggering, the student is eligible.

Step-by-step walkthrough

Let's trace through a record that fails the consecutive late rule.

Walkthrough: record = "PPALLL" (not eligible)

Step 1: Initialize and read index 0

absent = 0consec_late = 0
PPALLL^

Character is 'P'. Not 'A', so absent count stays 0. Not 'L', so consecutive late resets to 0.

Step 2: Read index 1

absent = 0consec_late = 0
PPALLL^

Character is 'P'. Same as before. Absent count stays 0, consecutive late stays 0.

Step 3: Read index 2

absent = 1consec_late = 0
PPALLL^

Character is 'A'. Increment absent count to 1. Reset consecutive late to 0. Still under the limit of 2.

Step 4: Read index 3

absent = 1consec_late = 1
PPALLL^

Character is 'L'. Increment consecutive late to 1. Absent count unchanged.

Step 5: Read index 4

absent = 1consec_late = 2
PPALLL^

Character is 'L'. Increment consecutive late to 2. Still under the limit of 3.

Step 6: Read index 5

absent = 1consec_late = 3
PPALLL^

Character is 'L'. Consecutive late becomes 3. That is 3 or more consecutive lates!

False

Result: Not eligible

absent = 1consec_late = 3
PPALLL

The student has 3 consecutive lates, which violates the rule. Return False.

False

The walkthrough shows how the consecutive late counter climbs to 3 at index 5, triggering an immediate False return. The absent count never reached 2, but that does not matter because the consecutive late rule was violated first.

Complexity analysis

ApproachTimeSpace
Single passO(n)O(1)

You visit each character exactly once, so the time is O(n) where n is the length of the string. You only maintain two integer counters, so space is O(1).

The building blocks

Character counting and consecutive tracking

This problem combines two common string scanning patterns:

  1. Global counting. Counting how many times a specific character appears across the entire string. You use this for the absent check.
  2. Consecutive streak tracking. Maintaining a running count that resets whenever the streak breaks. You use this for the late check.

Both patterns are useful independently, but this problem forces you to run them in parallel within the same loop. That combination appears in many real-world validation tasks: checking log files for repeated errors, validating input sequences, or scanning sensor data for anomalies.

Whenever a problem asks about both a total count and a consecutive run, think about maintaining two separate counters in one pass. One increments globally, the other resets on breaks. This avoids multiple passes or extra data structures.

Edge cases

  • All 'P' characters. "PPPPPP" returns True. Zero absences, zero lates.
  • Exactly one 'A'. "PA" returns True. One absence is still below the threshold.
  • Exactly two 'A's. "PAPA" returns False. Two absences violates the first rule.
  • Exactly two consecutive 'L's. "PLL" returns True. The limit is 3 or more, so 2 is fine.
  • Exactly three consecutive 'L's. "PLLL" returns False. Three consecutive lates triggers the rule.
  • Lates separated by other characters. "LLPLL" returns True. The consecutive streak resets at 'P', so the maximum streak is 2.
  • Empty string. "" returns True. No characters means no violations.
  • Single character. "A" returns True (1 absence, which is < 2). "L" returns True. "P" returns True.
  • Worst case at boundaries. "AALL" returns False because there are 2 absences, even though the consecutive lates are only 2.

From understanding to recall

Student Attendance Record I is a clean example of maintaining multiple state variables in a single scan. The logic itself is simple. The value of practicing it comes from internalizing the pattern of parallel counters: one that accumulates globally and one that resets on breaks. Three weeks from now, when you face a string problem that asks you to check two different conditions simultaneously, you want this pattern to come to mind immediately rather than requiring you to think from scratch.

Spaced repetition helps you reach that point. By revisiting this problem at increasing intervals, you train yourself to recognize the "count + streak" pattern and write the solution without hesitation.

Related posts

CodeBricks uses spaced repetition to help you internalize patterns like this one. Instead of solving hundreds of problems once and forgetting them, you revisit the key patterns at scientifically optimized intervals until they become automatic.