You are given a list of employee work schedules. Each employee has a list of non-overlapping time intervals representing when they are working. Each interval is represented as a pair of integers [start, end] where start < end.
Your task is to find all the time intervals when all employees are simultaneously free. Return these free time intervals in sorted order.
Example 1:
Input: schedule = [[[1,3],[4,6]], [[2,4],[7,9]]] Output: [[6,7]] Explanation: Employee 1 works: [1,3] and [4,6] Employee 2 works: [2,4] and [7,9] Merging all busy times: [1,6] and [7,9] Free time when all are available: [6,7]
Example 2:
Input: schedule = [[[1,3],[6,7]], [[2,4]], [[2,5],[9,12]]] Output: [[5,6],[7,9]] Explanation: Employee 1 works: [1,3], [6,7] Employee 2 works: [2,4] Employee 3 works: [2,5], [9,12] Merging all busy times: [1,5], [6,7], [9,12] Free intervals: [5,6] and [7,9]
Example 3:
Input: schedule = [[[1,10]], [[2,8]], [[3,6]]] Output: [] Explanation: All intervals overlap into one continuous period [1,10], so there are no gaps.
Hint 1: Flattening the Problem Think about how to convert this multi-employee problem into a simpler single-list problem. Can you combine all intervals from all employees into one unified collection?
Hint 2: Merge Then Find Gaps After collecting all working intervals from all employees, sort them and merge overlapping intervals. The gaps between merged intervals are the free times.
Hint 3: Alternative Approach with Events Consider using a sweep-line technique: treat each interval start and end as events. Track how many employees are working at any point. When the count drops to zero, you've found a free interval.
Full Solution `` Solution Explanation:
The key insight is to transform this multi-employee problem into a single interval merging problem:
- Flatten: Combine all work intervals from all employees into a single list. Since we want to find when everyone is free, we need to know when anyone is busy.
- Sort: Sort all intervals by their start time to prepare for merging.
- Merge: Iterate through sorted intervals and merge any that overlap. Two intervals
[a,b]and[c,d]overlap ifb >= c. When merging, we extend the end time to cover both intervals.- Find Gaps: After merging, any gap between consecutive merged intervals represents a time when no one is working (everyone is free).
Time Complexity: O(N log N) where N is the total number of intervals across all employees. Sorting dominates the complexity.
Space Complexity: O(N) for storing the flattened intervals and merged results.
Alternative Approach: A sweep-line algorithm using a min-heap can also solve this problem by processing interval endpoints in order and tracking the number of active workers at each point.
def findTeamFreeTime(schedule):
"""
Find intervals when all employees are free by merging busy intervals.
Approach:
1. Collect all work intervals from all employees into one list
2. Sort intervals by start time
3. Merge overlapping intervals to get consolidated busy periods
4. Find gaps between merged intervals (these are free times)
Time Complexity: O(N log N) where N is total number of intervals
Space Complexity: O(N) for storing and merging intervals
"""
# Step 1: Flatten all intervals from all employees
all_intervals = []
for employee_schedule in schedule:
for interval in employee_schedule:
all_intervals.append(interval)
# Edge case: no intervals
if not all_intervals:
return []
# Step 2: Sort by start time
all_intervals.sort(key=lambda x: x[0])
# Step 3: Merge overlapping intervals
merged = []
for interval in all_intervals:
if not merged or merged[-1][1] < interval[0]:
# No overlap, add as new interval
merged.append(interval)
else:
# Overlap exists, extend the last interval
merged[-1][1] = max(merged[-1][1], interval[1])
# Step 4: Find gaps between merged intervals
free_time = []
for i in range(len(merged) - 1):
# Gap exists between end of current and start of next
gap_start = merged[i][1]
gap_end = merged[i + 1][0]
if gap_start < gap_end:
free_time.append([gap_start, gap_end])
return free_time