Bird
Raised Fist0
Interview PrepintervalshardFacebookAmazonGoogle

Employee Free Time

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Steps
setup

Collect start and end events

We iterate over each employee's schedule and extract start and end times as events, marking starts with +1 and ends with -1.

💡 Separating intervals into start and end events allows us to process all interval boundaries uniformly.
Line:for emp in schedule: for interval in emp: events.append((interval[0], 1)) # start event events.append((interval[1], -1)) # end event
💡 This step transforms nested intervals into a flat list of events, preparing for sorting and sweeping.
📊
Employee Free Time - Watch the Algorithm Execute, Step by Step
Watching each event processed and how the active interval count changes reveals exactly when free time intervals appear, making the logic crystal clear.
Step 1/12
·Active fillAnswer cell
record
(1,1)
0
(2,-1)
1
(5,1)
2
(6,-1)
3
(1,1)
4
(3,-1)
5
(4,1)
6
(10,-1)
7
Result: []
record
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
record
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
move_right
i
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
move_right
(1,1)
0
i
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
move_right
(1,1)
0
(1,1)
1
i
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
move_right
(1,1)
0
(1,1)
1
(2,-1)
2
i
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: []
record
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
i
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: [[3,4]]
move_right
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
i
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: [[3,4]]
move_right
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
i
(6,-1)
6
(10,-1)
7
Result: [[3,4]]
move_right
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
i
(10,-1)
7
Result: [[3,4]]
record
(1,1)
0
(1,1)
1
(2,-1)
2
(3,-1)
3
(4,1)
4
(5,1)
5
(6,-1)
6
(10,-1)
7
Result: [[3,4]]

Key Takeaways

Transforming intervals into start and end events allows a uniform sweep line approach.

This insight is hard to see from code alone because the flattening and sorting steps are subtle but crucial.

Sorting events with end events before start events at the same time prevents counting intervals as active prematurely.

This ordering detail is easy to overlook but essential for correct active interval tracking.

When the active count drops to zero, the gap between previous and current event times is free time.

Watching the active count change step-by-step reveals exactly when free time intervals appear.

Practice

(1/5)
1. Consider the following Python code implementing the optimal car pooling solution. What is the return value when called with trips = [[2,1,5],[3,3,7]] and capacity = 4?
def carPooling(trips, capacity):
    max_location = 0
    for _, start, end in trips:
        max_location = max(max_location, end)
    diff = [0] * (max_location + 1)
    for num, start, end in trips:
        diff[start] += num
        diff[end] -= num
    current_passengers = 0
    for i in range(max_location + 1):
        current_passengers += diff[i]
        if current_passengers > capacity:
            return false
    return true

print(carPooling([[2,1,5],[3,3,7]], 4))
easy
A. Error due to index out of range
B. true
C. false
D. true only if capacity is at least 5

Solution

  1. Step 1: Build difference array

    diff after processing trips: diff[1]+=2, diff[5]-=2, diff[3]+=3, diff[7]-=3
  2. Step 2: Sweep through diff to track passengers

    At location 1: current_passengers=2; at 3: current_passengers=5 (2+3), which exceeds capacity=4 -> return false
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Passenger count exceeds capacity at location 3 [OK]
Hint: Sum diffs to track passengers, check capacity [OK]
Common Mistakes:
  • Off-by-one in diff array indexing
  • Checking capacity only at trip start
  • Forgetting to decrement at trip end
2. Given a list of train arrival and departure times, you need to find the minimum number of platforms required so that no train waits. Which approach guarantees an optimal solution for this problem?
easy
A. Use a greedy algorithm that assigns platforms as trains arrive without sorting times.
B. Use a sweep line algorithm by creating events for arrivals and departures, sorting them, and tracking concurrent trains.
C. Use dynamic programming to find the maximum overlap of intervals by building a state table.
D. Use nested loops to check every pair of trains for overlap and count maximum overlaps.

Solution

  1. Step 1: Understand the problem requires tracking concurrent trains

    The key is to find the maximum number of trains present at the station simultaneously.
  2. Step 2: Recognize that sorting events and sweeping through them tracks concurrency efficiently

    By creating arrival and departure events and sorting them, we can increment or decrement the count of trains present, capturing the peak count.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Sweep line tracks concurrency optimally [OK]
Hint: Sort events and sweep to track concurrency [OK]
Common Mistakes:
  • Assuming greedy assignment without sorting works
  • Trying DP which is unnecessary overhead
  • Using nested loops which is inefficient
3. Consider the following buggy code for inserting an interval. Which line contains the subtle bug that can cause incorrect output when the input list is empty?
from typing import List

def insert(intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
    intervals.append(newInterval)
    intervals.sort(key=lambda x: x[0])
    merged = [intervals[0]]
    for i in range(1, len(intervals)):
        if intervals[i][0] <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], intervals[i][1])
        else:
            merged.append(intervals[i])
    return merged
medium
A. Line 5: merged = [intervals[0]]
B. Line 3: intervals.append(newInterval)
C. Line 7: if intervals[i][0] <= merged[-1][1]:
D. Line 9: merged.append(intervals[i])

Solution

  1. Step 1: Consider empty intervals input

    If intervals is empty, after appending newInterval, intervals has length 1.
  2. Step 2: Check initialization of merged

    Line 5 accesses intervals[0] without checking if intervals is empty before append, which is safe here but if input was empty, intervals[0] is newInterval, so no crash.
  3. Step 3: Identify subtle bug

    Actually, no crash here, but if input intervals was empty, sorting and merging still works. The subtle bug is that if intervals was empty and newInterval is appended, the code works, but if the initial intervals list is empty and the code did not append newInterval first, line 5 would crash. So the bug is that the code assumes intervals is non-empty before append, which is not always true.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Accessing intervals[0] without empty check is risky [OK]
Hint: Accessing intervals[0] without empty check causes bug [OK]
Common Mistakes:
  • Not handling empty input intervals list
  • Assuming intervals always non-empty before append
  • Incorrect merging when intervals just touch
4. What is the time complexity of the sweep line algorithm for finding the minimum number of platforms required given n trains, and why?
medium
A. O(n log n) due to sorting arrivals and departures separately and merging them.
B. O(n^2) because each event is compared with all others to count overlaps.
C. O(n) because we only iterate through arrivals and departures once.
D. O(n log n) because events are sorted and then processed in a single pass.

Solution

  1. Step 1: Identify sorting as the main cost

    We create 2n events and sort them by time, which takes O(n log n).
  2. Step 2: Single pass processing after sorting

    After sorting, we iterate through events once, O(n), updating counts.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sorting dominates, linear sweep after [OK]
Hint: Sorting events dominates time complexity [OK]
Common Mistakes:
  • Assuming O(n) because of single pass ignoring sorting
  • Confusing nested loops brute force with sweep line
  • Thinking sorting arrivals and departures separately is enough
5. Suppose trains can arrive and depart multiple times (reusing platforms) and the schedule may include negative time values (e.g., early morning times). Which modification to the sweep line algorithm ensures correct minimum platform calculation?
hard
A. Use the same sweep line approach but ensure sorting handles negative times correctly and process events with departure before arrival on tie.
B. Use dynamic programming to handle multiple arrivals and departures per train.
C. Switch to nested loops checking overlaps since negative times break sorting assumptions.
D. Ignore negative times and treat them as zero to simplify sorting.

Solution

  1. Step 1: Recognize that negative times do not affect event sorting if handled correctly

    Sorting supports negative values naturally; no need to ignore or clamp them.
  2. Step 2: Maintain departure-before-arrival ordering on tie to avoid overcounting

    This ordering is critical regardless of time values or multiple arrivals/departures.
  3. Step 3: Continue using sweep line approach for efficiency and correctness

    Nested loops or DP are inefficient or unnecessary for this variant.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Sweep line with correct sorting handles negative and multiple events [OK]
Hint: Sorting handles negative times; keep departure before arrival on tie [OK]
Common Mistakes:
  • Ignoring negative times or clamping them
  • Switching to inefficient nested loops unnecessarily
  • Misordering events causing overcounting