Facebook Pixel

1450. Number of Students Doing Homework at a Given Time

Problem Description

You are given information about students doing their homework. Each student has a start time and end time for when they begin and complete their homework.

The problem provides three inputs:

  • startTime: An array where startTime[i] represents when the i-th student starts their homework
  • endTime: An array where endTime[i] represents when the i-th student finishes their homework
  • queryTime: A specific time point you want to check

Your task is to count how many students are actively doing homework at the given queryTime. A student is considered to be doing homework at queryTime if queryTime falls within their homework time interval [startTime[i], endTime[i]] (inclusive on both ends).

For example, if a student starts homework at time 3 and ends at time 7, they would be counted as doing homework for any queryTime value from 3 to 7 (including 3 and 7).

The solution uses a straightforward approach by iterating through all students using zip(startTime, endTime) to pair up each student's start and end times. For each pair (x, y), it checks if x <= queryTime <= y. The sum() function counts how many students satisfy this condition, giving us the total number of students doing homework at queryTime.

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

Intuition

The key insight here is recognizing that we need to check a simple condition for each student: is the query time within their homework period?

Think of it like checking if a specific moment in time overlaps with multiple time intervals. Each student represents one interval from their start time to end time. We want to know how many of these intervals contain our query point.

Since we need to check every student to get an accurate count, there's no way to avoid looking at each one. This naturally leads us to iterate through all students and check the condition for each.

The condition itself is straightforward - a time point falls within an interval if it's greater than or equal to the start and less than or equal to the end. In Python, this translates elegantly to x <= queryTime <= y.

Rather than using a traditional loop with a counter variable, we can leverage Python's ability to treat boolean expressions as 1 (True) or 0 (False) in numeric contexts. By using sum() with a generator expression that yields True/False for each student, we automatically count the number of True values, which gives us our answer.

The zip(startTime, endTime) pairs up corresponding elements from both arrays, allowing us to process each student's start and end times together in a clean, readable way.

Solution Approach

The solution implements a direct traversal approach to count students doing homework at the query time.

Step-by-step implementation:

  1. Pairing the arrays: We use zip(startTime, endTime) to create pairs of corresponding start and end times. This gives us tuples like (startTime[0], endTime[0]), (startTime[1], endTime[1]), and so on, where each tuple represents one student's homework interval.

  2. Checking each interval: For each pair (x, y) obtained from the zip operation:

    • x represents when a student starts homework
    • y represents when they finish
    • We check if x <= queryTime <= y to determine if the student is doing homework at queryTime
  3. Counting with sum(): The expression x <= queryTime <= y evaluates to a boolean (True or False). In Python, when used in a numeric context like sum():

    • True is treated as 1
    • False is treated as 0

    By summing all these boolean values, we get the total count of students doing homework.

  4. Generator expression: Instead of creating a list and then summing it, we use a generator expression inside sum(). This is more memory-efficient as it evaluates one item at a time rather than creating an entire list in memory.

The complete solution in one line:

return sum(x <= queryTime <= y for x, y in zip(startTime, endTime))

This approach has a time complexity of O(n) where n is the number of students, as we check each student exactly once. The space complexity is O(1) since we only use a constant amount of extra space for the iteration variables.

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Let's walk through a concrete example to understand how the solution works.

Given:

  • startTime = [1, 2, 3]
  • endTime = [3, 2, 7]
  • queryTime = 4

We want to find how many students are doing homework at time 4.

Step 1: Pair up the arrays using zip

zip(startTime, endTime) creates pairs:
- Student 0: (1, 3)
- Student 1: (2, 2)
- Student 2: (3, 7)

Step 2: Check each student

For Student 0 with interval [1, 3]:

  • Check: Is 1 ≤ 4 ≤ 3?
  • 1 ≤ 4 is True, but 4 ≤ 3 is False
  • Overall: False (0)

For Student 1 with interval [2, 2]:

  • Check: Is 2 ≤ 4 ≤ 2?
  • 2 ≤ 4 is True, but 4 ≤ 2 is False
  • Overall: False (0)

For Student 2 with interval [3, 7]:

  • Check: Is 3 ≤ 4 ≤ 7?
  • 3 ≤ 4 is True, and 4 ≤ 7 is True
  • Overall: True (1)

Step 3: Sum the results

sum([False, False, True]) = sum([0, 0, 1]) = 1

Result: 1 student is doing homework at time 4.

The solution efficiently counts this in one line:

return sum(x <= queryTime <= y for x, y in zip(startTime, endTime))

This generates: FalseFalseTrue, which sums to 1.

Solution Implementation

1class Solution:
2    def busyStudent(
3        self, startTime: List[int], endTime: List[int], queryTime: int
4    ) -> int:
5        """
6        Count the number of students doing homework at a given query time.
7      
8        A student is considered busy if the query time falls within their
9        homework period [startTime[i], endTime[i]] (inclusive).
10      
11        Args:
12            startTime: List of integers representing when each student starts homework
13            endTime: List of integers representing when each student finishes homework
14            queryTime: Integer representing the time to check how many students are busy
15          
16        Returns:
17            Integer count of students doing homework at queryTime
18        """
19        # Count students where queryTime falls within their homework period
20        # For each student i, check if startTime[i] <= queryTime <= endTime[i]
21        busy_count = sum(
22            start <= queryTime <= end 
23            for start, end in zip(startTime, endTime)
24        )
25      
26        return busy_count
27
1class Solution {
2    /**
3     * Counts the number of students doing homework at a given query time.
4     * A student is considered busy if the query time falls within their study period (inclusive).
5     * 
6     * @param startTime Array where startTime[i] represents when student i starts homework
7     * @param endTime Array where endTime[i] represents when student i finishes homework
8     * @param queryTime The specific time to check how many students are busy
9     * @return The number of students doing homework at queryTime
10     */
11    public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
12        // Initialize counter for busy students
13        int busyStudentCount = 0;
14      
15        // Iterate through each student
16        for (int i = 0; i < startTime.length; i++) {
17            // Check if queryTime falls within the student's study period (inclusive)
18            if (startTime[i] <= queryTime && queryTime <= endTime[i]) {
19                // Increment count if student is busy at queryTime
20                busyStudentCount++;
21            }
22        }
23      
24        // Return the total number of busy students
25        return busyStudentCount;
26    }
27}
28
1class Solution {
2public:
3    int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
4        // Initialize counter for students doing homework at query time
5        int studentCount = 0;
6      
7        // Iterate through all students
8        for (int i = 0; i < startTime.size(); ++i) {
9            // Check if the query time falls within the student's homework period (inclusive)
10            // A student is busy if: startTime[i] <= queryTime <= endTime[i]
11            if (startTime[i] <= queryTime && queryTime <= endTime[i]) {
12                studentCount++;
13            }
14        }
15      
16        // Return the total number of students doing homework at query time
17        return studentCount;
18    }
19};
20
1/**
2 * Counts the number of students doing their homework at a given query time.
3 * A student is considered busy if the query time falls within their study period (inclusive).
4 * 
5 * @param startTime - Array of start times for each student's homework session
6 * @param endTime - Array of end times for each student's homework session
7 * @param queryTime - The time point to check how many students are studying
8 * @returns The number of students doing homework at the query time
9 */
10function busyStudent(startTime: number[], endTime: number[], queryTime: number): number {
11    // Get the total number of students
12    const studentCount: number = startTime.length;
13  
14    // Initialize counter for busy students
15    let busyStudentCount: number = 0;
16  
17    // Iterate through each student's schedule
18    for (let i: number = 0; i < studentCount; i++) {
19        // Check if query time falls within the student's study period (inclusive)
20        if (startTime[i] <= queryTime && queryTime <= endTime[i]) {
21            busyStudentCount++;
22        }
23    }
24  
25    // Return the total count of busy students
26    return busyStudentCount;
27}
28

Time and Space Complexity

The time complexity is O(n), where n is the number of students (or the length of the startTime and endTime lists). The algorithm iterates through both lists exactly once using zip(), and for each pair of values, it performs a constant-time comparison operation to check if queryTime falls within the range [x, y]. The sum() function then counts the number of True values from this iteration.

The space complexity is O(1). The algorithm uses only a constant amount of extra space. While zip() creates an iterator that pairs elements from the two lists, it doesn't create a new list in memory - it generates pairs on-the-fly. The generator expression (x <= queryTime <= y for x, y in zip(startTime, endTime)) also doesn't store all results in memory at once; it yields values one at a time to the sum() function. The only additional space used is for the loop variables x and y and the accumulator in sum(), all of which require constant space regardless of input size.

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

Common Pitfalls

1. Assuming Arrays Have Equal Length

One common pitfall is not considering that startTime and endTime arrays might have different lengths due to data corruption or input errors. While the problem statement implies they should be equal, defensive programming suggests validating this assumption.

Problem Example:

startTime = [1, 2, 3]
endTime = [5, 6]  # Missing one end time
queryTime = 4

Solution: Add a validation check or handle mismatched lengths gracefully:

def busyStudent(self, startTime, endTime, queryTime):
    # Validate input arrays have same length
    if len(startTime) != len(endTime):
        # Handle based on requirements - could raise exception or process minimum
        min_length = min(len(startTime), len(endTime))
        return sum(startTime[i] <= queryTime <= endTime[i] 
                  for i in range(min_length))
  
    return sum(start <= queryTime <= end 
              for start, end in zip(startTime, endTime))

2. Not Handling Invalid Time Intervals

Another pitfall is assuming all time intervals are valid (i.e., startTime[i] <= endTime[i]). In real-world data, you might encounter cases where end time is before start time.

Problem Example:

startTime = [1, 5, 3]
endTime = [4, 2, 7]  # Second student has endTime < startTime
queryTime = 3

Solution: Either filter out invalid intervals or handle them explicitly:

def busyStudent(self, startTime, endTime, queryTime):
    return sum(
        start <= queryTime <= end 
        for start, end in zip(startTime, endTime)
        if start <= end  # Only count valid intervals
    )

3. Integer Overflow in Other Languages

While not an issue in Python, developers translating this solution to languages like C++ or Java might face integer overflow if time values are very large.

Solution for other languages: Use appropriate data types (like long in Java) or ensure input constraints are well-defined.

4. Modifying the Solution for Exclusive Intervals

A subtle pitfall occurs when requirements change to exclusive intervals. The current solution uses inclusive bounds [startTime, endTime]. If the problem required exclusive bounds or mixed bounds like [startTime, endTime), the comparison operators need adjustment.

Solution for exclusive end time:

def busyStudent(self, startTime, endTime, queryTime):
    return sum(
        start <= queryTime < end  # Note: < instead of <=
        for start, end in zip(startTime, endTime)
    )
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

The three-steps of Depth First Search are:

  1. Identify states;
  2. Draw the state-space tree;
  3. DFS on the state-space tree.

Recommended Readings

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

Load More