Вы можете сохранить сбойные сегменты, которые в данный момент «активны», в куче, отсортированные по их конечному значению, а затем извлечь их из кучи, когда это конечное значение меньше конца текущего сегмента.Затем, если в куче есть какие-либо элементы, текущий сегмент завершается ошибкой.
import heapq
segments = [(1,2), (3,4), (5,7), (9,10)]
fail = [(0,4), (8,11)]
idx = 0
covering = []
for (start, end) in segments:
while idx < len(fail) and fail[idx][0] <= start:
heapq.heappush(covering, fail[idx][1])
idx += 1
while covering and covering[0] < end:
heapq.heappop(covering)
print(start, end, covering)
Пример вывода:
1 2 [4]
3 4 [4]
5 7 []
9 10 [11]
Таким образом, вы не только узнаете , если текущий сегмент терпит неудачу, но также и какой и сколько неудачных сегментов он пересекает.Обратите внимание, что если вы хотите поместить полный отказавший сегмент в кучу, вы должны использовать кортеж (end, f_seg)
, чтобы гарантировать, что тот, у кого самый низкий end
, будет отсортирован первым в куче.
Конечно,если вам не нужно знать, какие или сколько ошибочных сегментов пересекаются, вы можете просто отслеживать максимальное конечное значение любого из уже запущенных ошибочных сегментов без использования кучи.
idx = 0
last_fail = -1
for (start, end) in segments:
while idx < len(fail) and fail[idx][0] <= start:
last_fail = max(last_fail, fail[idx][1])
idx += 1
print(start, end, last_fail >= end)
Сложность для решения на основе кучи будет O (n + mlogm) для n сегментов и m fail-сегментов, и просто O (n+ м) без кучи.(Предполагая, что оба списка уже отсортированы.)