Solution
-
The tasks which appear more times is the bottle neck.
-
We store the number of times each task appeared. Use heapq to sort it.
-
Use the top tasks to fill in the time units we need between two same tasks.
-
When there is not enough tasks, None is appended.
-
We need to update the number of times of each tasks, to avoid affecting step 3, we keep all tasks that need to be updated in a list, and update them in the end of this loop.
def leastInterval(self, tasks, n):
"""
:type tasks: List[str]
:type n: int
:rtype: int
"""
# Get the number of chars
times = [(0, '')] * 26
for task in tasks:
times[ord(task) - ord('A')] = (times[ord(task) - ord('A')][0] - 1,
task)
heapq.heapify(times)
res = []
while len(times) != 0:
top = heapq.heappop(times)
top_time = top[0]
top_char = top[1]
while top_time != 0:
top_time += 1
res.append(top_char)
skip = 0
temp = []
while skip != n:
if len(times) != 0:
next_t = heapq.heappop(times)
if next_t[0] < 0:
temp.append(next_t)
res.append(next_t[1])
skip += 1
continue
res += [None] * (n - skip)
skip += n - skip
for tmp in temp:
heapq.heappush(times, (tmp[0] + 1, tmp[1]))
tail = 0
for i in range(len(res)-1, -1, -1):
if not res[i]:
tail += 1
else:
break
return len(res) - tail
Solution - O(N)
-
Build a dictionary for tasks
-
Make
max_occ - 1
groups, groups size = n+1. Fill each group with uniform iterleaving as even as possible -
At last, execute for the last time of max_occ jobs
def leastInterval(self, tasks: List[str], n: int) -> int:
if n == 0:
return len(tasks)
task_occ_dict = Counter( tasks )
# max occurrence among tasks
max_occ = max( task_occ_dict.values() )
# number of tasks with max occurrence
number_of_taks_of_max_occ = sum( ( 1 for task, occ in task_occ_dict.items() if occ == max_occ ) )
# Make (max_occ-1) groups, each groups size is (n+1) to meet the requirement of cooling
# Fill each group with uniform iterleaving as even as possible
# At last, execute for the last time of max_occ jobs
intervl_for_schedule = ( max_occ-1 )*( n+1 ) + number_of_taks_of_max_occ
# Minimal length is original length on best case.
# Otherswise, it need some cooling intervals in the middle
return max( len(tasks), intervl_for_schedule)
PREVIOUSDecode String