将会议时间列表分配给会议室
Assigning a list of meeting times to meeting rooms
给定会议时间段列表,我试图将它们分配到会议室(同时使用最少的房间)。它工作得相当好,但它 returns 有时值不正确,我不明白为什么。
from typing import List, Tuple
import heapq
def offer(begin:int, end:int, heap:List[int]) -> int:
while heap and heap[0] <= begin:
heapq.heappop(heap)
heapq.heappush(heap, end)
return len(heap)
def schedule(times:List[Tuple[int, int]]):
heap = []
groups = defaultdict(list)
for begin, end in sorted(times):
key = offer(begin, end, heap)
groups[key].append( (begin, end))
return groups
1) 测试成功:
times = [(12, 13), (12, 15), (17, 20)]
assert schedule(times) == [(1, (12, 13)), (2, (12, 15)), (1, (17, 20))] # works
2) 测试成功:
一个更复杂的案例。
times = [(12,13), (13,15), (17,20), (13,14), (19 , 21), (18, 20), (12,13)]
assert schedule(vals) == {
1: [(12, 13), (13,14),(17, 20)],
2: [(12, 13), (13, 15), (18, 20),],
3: [(19, 21)],
} # works
3) 不成功
看似简单但失败
times = [(12, 16), (15,18), (17,20)]
assert schedule(times) == {
1: [(12, 16), (17,20)],
2: [(15,18)],
} # error
而是将两个会议分配到明显重叠的第二个房间:
defaultdict(list, {1: [(12, 16)], 2: [(15, 18), (17, 20)]})
问题是您没有跟踪当前哪些房间是空闲的。您的 'offer' 代码假定如果有一个房间正在使用(即 len(heap)==1
),则它始终是第一个房间。要解决此问题,请跟踪哪些房间空闲:
def offer(begin: int, end: int, heap: List[Tuple[int, int]], free_rooms: List[int]) -> int:
while heap and heap[0][0] <= begin:
free_rooms.append(heapq.heappop(heap)[1])
if not free_rooms:
some_free_room = len(heap) + 1
else:
some_free_room = free_rooms.pop()
heapq.heappush(heap, (end, some_free_room))
return some_free_room
def schedule(times: List[Tuple[int, int]]):
heap = []
free_rooms = []
groups = defaultdict(list)
for begin, end in sorted(times):
key = offer(begin, end, heap, free_rooms)
groups[key].append((begin, end))
return groups
此代码可能仍无法通过其中一些测试。原因是在分配最少的房间时有不止一种安排方式;您正在检查特定分配。如果你还想要我们应该贪婪地使用第一个空闲房间的属性,你将需要另一个堆:
def offer_first_free(begin: int, end: int, heap: List[Tuple[int, int]], free_rooms: List[int]) -> int:
while heap and heap[0][0] <= begin:
heapq.heappush(free_rooms, heapq.heappop(heap)[1])
if not free_rooms:
first_free_room = len(heap) + 1
else:
first_free_room = heapq.heappop(free_rooms)
heapq.heappush(heap, (end, first_free_room))
return first_free_room
给定会议时间段列表,我试图将它们分配到会议室(同时使用最少的房间)。它工作得相当好,但它 returns 有时值不正确,我不明白为什么。
from typing import List, Tuple
import heapq
def offer(begin:int, end:int, heap:List[int]) -> int:
while heap and heap[0] <= begin:
heapq.heappop(heap)
heapq.heappush(heap, end)
return len(heap)
def schedule(times:List[Tuple[int, int]]):
heap = []
groups = defaultdict(list)
for begin, end in sorted(times):
key = offer(begin, end, heap)
groups[key].append( (begin, end))
return groups
1) 测试成功:
times = [(12, 13), (12, 15), (17, 20)]
assert schedule(times) == [(1, (12, 13)), (2, (12, 15)), (1, (17, 20))] # works
2) 测试成功:
一个更复杂的案例。
times = [(12,13), (13,15), (17,20), (13,14), (19 , 21), (18, 20), (12,13)]
assert schedule(vals) == {
1: [(12, 13), (13,14),(17, 20)],
2: [(12, 13), (13, 15), (18, 20),],
3: [(19, 21)],
} # works
3) 不成功
看似简单但失败
times = [(12, 16), (15,18), (17,20)]
assert schedule(times) == {
1: [(12, 16), (17,20)],
2: [(15,18)],
} # error
而是将两个会议分配到明显重叠的第二个房间:
defaultdict(list, {1: [(12, 16)], 2: [(15, 18), (17, 20)]})
问题是您没有跟踪当前哪些房间是空闲的。您的 'offer' 代码假定如果有一个房间正在使用(即 len(heap)==1
),则它始终是第一个房间。要解决此问题,请跟踪哪些房间空闲:
def offer(begin: int, end: int, heap: List[Tuple[int, int]], free_rooms: List[int]) -> int:
while heap and heap[0][0] <= begin:
free_rooms.append(heapq.heappop(heap)[1])
if not free_rooms:
some_free_room = len(heap) + 1
else:
some_free_room = free_rooms.pop()
heapq.heappush(heap, (end, some_free_room))
return some_free_room
def schedule(times: List[Tuple[int, int]]):
heap = []
free_rooms = []
groups = defaultdict(list)
for begin, end in sorted(times):
key = offer(begin, end, heap, free_rooms)
groups[key].append((begin, end))
return groups
此代码可能仍无法通过其中一些测试。原因是在分配最少的房间时有不止一种安排方式;您正在检查特定分配。如果你还想要我们应该贪婪地使用第一个空闲房间的属性,你将需要另一个堆:
def offer_first_free(begin: int, end: int, heap: List[Tuple[int, int]], free_rooms: List[int]) -> int:
while heap and heap[0][0] <= begin:
heapq.heappush(free_rooms, heapq.heappop(heap)[1])
if not free_rooms:
first_free_room = len(heap) + 1
else:
first_free_room = heapq.heappop(free_rooms)
heapq.heappush(heap, (end, first_free_room))
return first_free_room