-
Notifications
You must be signed in to change notification settings - Fork 0
LC 0759 [H] Employee Free Time
Code with Senpai edited this page May 20, 2022
·
1 revision
the naive solution re-sorts and is "merge sorted intervals" sorting for O(nlogn) [LC medium]
# O(nlogn)
class Solution:
def employeeFreeTime(self, schedule: 'list<list<Interval>>') -> 'list<Interval>':
intervals = sorted([i for s in schedule for i in s], key=lambda x: x.start)
res, end = [], intervals[0].end
for i in intervals[1:]:
if i.start > end:
res.append(Interval(end, i.start))
end = max(end, i.end)
return res
but the correct and optimized solution takes advantage of how the employee schedules are already sorted, so it's more like "merge k sorted" which uses heap for O(nlogk) [LC hard]
# O(nlogk)
"""
# Definition for an Interval.
class Interval:
def __init__(self, start: int = None, end: int = None):
self.start = start
self.end = end
"""
from queue import PriorityQueue
class Solution:
def employeeFreeTime(self, schedule: '[[Interval]]') -> '[Interval]':
min_heap = PriorityQueue()
res = []
for e in range(len(schedule)):
# queue the first interval for each employee in order from the front
min_heap.put( (schedule[e][0].start, schedule[e][0].end, e) )
schedule[e].pop(0)
end = min_heap.queue[0][1] # earliest interval by start, end, employee
while not min_heap.empty():
new_start, new_end, e = min_heap.get()
if new_start <= end:
# is overlapping = common time, extend it
end = max(end, new_end)
else: # (new_start > end), so (end, new_start)
# not common time, add it
res.append(Interval(end, new_start))
end = new_end # is set behind so we can look for next common time
# queue next employee interval
if schedule[e]:
min_heap.put( (schedule[e][0].start, schedule[e][0].end, e) )
schedule[e].pop(0)
return res
footer