Если значения можно использовать в качестве ключей dict, тогда было бы довольно легко использовать как кучу, так и collections.Counter
, чтобы отслеживать, сколько из каждого значения концептуально все еще находится в коллекции.Отсчет 0 означает, что значение было концептуально полностью удалено, хотя оно все еще может существовать в куче.
Вот эскиз (не проверено!), Где c
- это экземпляр collections.Counter
и h
- это список, используемый в качестве кучи для операций модуля heapq
:
Чтобы добавить элемент (логарифмическое время ожидаемого случая в размере кучи):
heapq.heappush(h, elt)
c[elt] += 1
Чтобы удалить элемент(постоянное время в ожидаемом случае):
if not c[elt]:
raise ValueError("element doesn't exist")
c[elt] -= 1
if not c[elt]:
del c[elt]
Чтобы удалить минимальный элемент (логарифмическое время в ожидаемом случае (в уменьшающемся размере кучи)) для каждого концептуально извлеченного ранее удаленного элементаиз кучи):
while True:
if not h:
raise ValueError("cannot find minimum in empty collection")
elt = heapq.heappop(h)
if c[elt]:
c[elt] -= 1
if not c[elt]:
del c[elt]
break
# else the Counter believes it was deleted earlier