Facebook Pixel

551. Student Attendance Record I

EasyString
Leetcode Link

Problem Description

You need to determine if a student qualifies for an attendance award based on their attendance record string s.

The attendance record consists of three possible characters:

  • 'A' represents Absent
  • 'L' represents Late
  • 'P' represents Present

To be eligible for the attendance award, the student must satisfy both conditions:

  1. Absence Rule: The student must have been absent ('A') for less than 2 days total throughout the entire record. This means at most 1 absence is allowed.
  2. Late Rule: The student must never have been late ('L') for 3 or more consecutive days. Patterns like 'LLL' would disqualify the student.

Return true if the student meets both criteria and qualifies for the award, otherwise return false.

The solution elegantly checks both conditions:

  • s.count('A') < 2 verifies that there are fewer than 2 absences in total
  • 'LLL' not in s ensures there are no 3 consecutive late days

Both conditions must be true for the student to be eligible, which is why they are combined with the and operator.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

When we look at this problem, we need to check two independent conditions on the attendance string. The key insight is that these conditions are straightforward to verify directly without any complex algorithms.

For the first condition (fewer than 2 absences), we simply need to count how many times 'A' appears in the entire string. If we find 0 or 1 absence, the student passes this criterion. Counting occurrences of a character in a string is a basic operation that most programming languages support directly.

For the second condition (no 3 consecutive lates), we need to detect if the pattern 'LLL' exists anywhere in the string. Rather than manually iterating through the string and checking every group of three consecutive characters, we can use substring search. The pattern 'LLL' is fixed and simple - we just need to check if this exact sequence appears anywhere in our string.

The beauty of this approach is its simplicity. Instead of writing loops or maintaining counters for consecutive lates, we leverage built-in string operations:

  • s.count('A') gives us the total number of absences
  • 'LLL' in s tells us whether three consecutive lates exist

Since both conditions must be satisfied for the student to be eligible, we combine them with a logical and. The final check becomes: ensure absences are less than 2 AND ensure 'LLL' doesn't exist in the string.

This direct approach is both efficient and readable, making the solution immediately understandable while avoiding unnecessary complexity.

Solution Approach

The implementation uses a single-line solution that leverages Python's built-in string methods to check both attendance criteria:

def checkRecord(self, s: str) -> bool:
    return s.count('A') < 2 and 'LLL' not in s

Let's break down each component:

1. Checking Absences: s.count('A') < 2

The count() method iterates through the string and returns the total number of occurrences of the character 'A'. This operation has a time complexity of O(n) where n is the length of the string. We then check if this count is less than 2, which ensures the student has been absent for strictly fewer than 2 days.

2. Checking Consecutive Lates: 'LLL' not in s

Python's in operator performs substring search to check if 'LLL' exists anywhere in the string s. Under the hood, this uses an efficient string searching algorithm (typically a variant of Boyer-Moore or similar). The not in operator returns True if the pattern 'LLL' is NOT found, which is exactly what we want - the student should never have 3 consecutive late days.

3. Combining Conditions with and

Both conditions must be satisfied for the student to be eligible. The and operator ensures that the function returns True only when:

  • The absence count is less than 2, AND
  • The string doesn't contain three consecutive lates

Time and Space Complexity:

  • Time Complexity: O(n) where n is the length of the string. Both count() and substring search operations traverse the string.
  • Space Complexity: O(1) as we only use constant extra space for the count result and boolean checks.

This approach is optimal because we must examine every character at least once to verify both conditions, and we do so with minimal passes through the string.

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with a concrete example to see how it evaluates both conditions.

Example 1: s = "PPALLP"

Step 1: Check the absence condition with s.count('A') < 2

  • Scan through the string: P-P-A-L-L-P
  • Count of 'A' = 1
  • Is 1 < 2? Yes ✓

Step 2: Check the consecutive late condition with 'LLL' not in s

  • Look for substring 'LLL' in "PPALLP"
  • We have 'LL' at positions 3-4, but not 'LLL'
  • Is 'LLL' NOT in the string? Yes ✓

Step 3: Combine with and

  • Both conditions are True
  • Result: True (student qualifies for the award)

Example 2: s = "PPALLL"

Step 1: Check s.count('A') < 2

  • Count of 'A' = 1
  • Is 1 < 2? Yes ✓

Step 2: Check 'LLL' not in s

  • Look for substring 'LLL' in "PPALLL"
  • Found 'LLL' at positions 3-5
  • Is 'LLL' NOT in the string? No ✗

Step 3: Combine with and

  • First condition is True, second is False
  • Result: False (student doesn't qualify - too many consecutive lates)

Example 3: s = "AAPPALL"

Step 1: Check s.count('A') < 2

  • Scan: A-A-P-P-A-L-L
  • Count of 'A' = 3
  • Is 3 < 2? No ✗

Step 2: Check 'LLL' not in s

  • No need to check (first condition already failed)
  • For completeness: 'LLL' is not in the string

Step 3: Combine with and

  • First condition is False
  • Result: False (student doesn't qualify - too many absences)

The solution efficiently handles all cases by checking both rules in a single return statement, immediately identifying whether a student qualifies for the attendance award.

Solution Implementation

1class Solution:
2    def checkRecord(self, s: str) -> bool:
3        """
4        Check if a student's attendance record is eligible for an award.
5      
6        A student is eligible if:
7        1. They were absent ('A') fewer than 2 days total
8        2. They were never late ('L') for 3 or more consecutive days
9      
10        Args:
11            s: A string representing the attendance record where:
12               'A' = Absent
13               'L' = Late  
14               'P' = Present
15      
16        Returns:
17            bool: True if the student is eligible for an award, False otherwise
18        """
19        # Check if absences are fewer than 2
20        absent_count = s.count('A')
21      
22        # Check if there are 3 consecutive late days
23        has_three_consecutive_lates = 'LLL' in s
24      
25        # Student is eligible if both conditions are met:
26        # - Fewer than 2 absences AND
27        # - No occurrence of 3 consecutive late days
28        return absent_count < 2 and not has_three_consecutive_lates
29
1class Solution {
2    /**
3     * Checks if a student's attendance record qualifies for an attendance award.
4     * The student qualifies if:
5     * 1. They were absent ('A') for strictly fewer than 2 days total
6     * 2. They were never late ('L') for 3 or more consecutive days
7     * 
8     * @param s the attendance record string containing 'A' (Absent), 'L' (Late), 'P' (Present)
9     * @return true if the student qualifies for the award, false otherwise
10     */
11    public boolean checkRecord(String s) {
12        // Check if student has at most one absence by verifying first and last occurrence of 'A' are the same
13        // If indexOf and lastIndexOf return the same value, 'A' appears at most once
14        // (both return -1 if no 'A', or same index if exactly one 'A')
15        boolean hasAtMostOneAbsence = s.indexOf("A") == s.lastIndexOf("A");
16      
17        // Check if student was never late for 3 consecutive days
18        boolean noThreeConsecutiveLates = !s.contains("LLL");
19      
20        // Student qualifies only if both conditions are met
21        return hasAtMostOneAbsence && noThreeConsecutiveLates;
22    }
23}
24
1class Solution {
2public:
3    bool checkRecord(string s) {
4        // Check two conditions for a valid attendance record:
5        // 1. The student was absent ('A') fewer than 2 days (0 or 1 day)
6        // 2. The student was never late ('L') for 3 or more consecutive days
7      
8        // Count the number of 'A' (Absent) in the string
9        int absenceCount = count(s.begin(), s.end(), 'A');
10      
11        // Check if there are 3 consecutive 'L' (Late) in the string
12        bool hasThreeConsecutiveLates = (s.find("LLL") != string::npos);
13      
14        // Return true if both conditions are satisfied:
15        // - Less than 2 absences AND
16        // - No occurrence of 3 consecutive lates
17        return absenceCount < 2 && !hasThreeConsecutiveLates;
18    }
19};
20
1/**
2 * Checks if a student's attendance record qualifies for an attendance award.
3 * A student qualifies if they have fewer than 2 absences ('A') and no more than 2 consecutive late days ('L').
4 * 
5 * @param s - The attendance record string containing 'A' (Absent), 'L' (Late), and 'P' (Present)
6 * @returns true if the student qualifies for the award, false otherwise
7 */
8function checkRecord(s: string): boolean {
9    // Check two conditions:
10    // 1. At most one 'A': indexOf('A') equals lastIndexOf('A') means 'A' appears at most once
11    //    - If no 'A' exists, both return -1 (equal)
12    //    - If one 'A' exists, both return the same index (equal)
13    //    - If multiple 'A's exist, they return different indices (not equal)
14    const hasAtMostOneAbsence: boolean = s.indexOf('A') === s.lastIndexOf('A');
15  
16    // 2. No three consecutive 'L's: indexOf('LLL') returns -1 if pattern not found
17    const hasNoThreeConsecutiveLates: boolean = s.indexOf('LLL') === -1;
18  
19    // Student qualifies only if both conditions are met
20    return hasAtMostOneAbsence && hasNoThreeConsecutiveLates;
21}
22

Time and Space Complexity

Time Complexity: O(n)

The time complexity is linear where n is the length of the string s. This is because:

  • s.count('A') iterates through the entire string once to count occurrences of 'A', which takes O(n) time
  • 'LLL' not in s performs a substring search that in the worst case needs to check each position in the string, which takes O(n) time for the pattern of fixed length 3
  • These two operations are performed sequentially (not nested), so the overall time complexity remains O(n)

Space Complexity: O(1)

The space complexity is constant because:

  • The count() method only uses a counter variable to track the number of 'A's
  • The substring search 'LLL' not in s only needs constant extra space to perform the pattern matching
  • No additional data structures that scale with input size are created
  • The function only returns a boolean value

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Misunderstanding the Absence Requirement

A common mistake is interpreting "less than 2 days" as "at most 2 days" and writing:

# WRONG - This allows 2 absences
return s.count('A') <= 2 and 'LLL' not in s

The correct condition is s.count('A') < 2, which means the student can have 0 or 1 absence only.

2. Incorrect Consecutive Late Check

Some developers try to manually check for consecutive lates using loops or counters:

# WRONG - Overly complex and error-prone
late_count = 0
for char in s:
    if char == 'L':
        late_count += 1
        if late_count >= 3:  # Bug: doesn't reset counter
            return False
    # Missing: else late_count = 0
return s.count('A') < 2

This approach often forgets to reset the counter when a non-'L' character is encountered.

Solution: Use the simpler substring check 'LLL' not in s which handles all edge cases automatically.

3. Using OR Instead of AND

Another mistake is using or operator instead of and:

# WRONG - Student must meet BOTH conditions, not just one
return s.count('A') < 2 or 'LLL' not in s

This would incorrectly award a student who has 3 consecutive lates but no absences.

4. Case Sensitivity Issues

If the input isn't guaranteed to be uppercase, forgetting to handle case sensitivity:

# WRONG if input could be lowercase
return s.count('A') < 2 and 'LLL' not in s

Solution: Normalize the input first if needed:

s = s.upper()
return s.count('A') < 2 and 'LLL' not in s

5. Not Handling Empty Strings

While the current solution correctly handles empty strings (returns True), some manual implementations might not consider this edge case. An empty attendance record should qualify for the award since there are no violations.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

Which of the following shows the order of node visit in a Breadth-first Search?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More