Pythons heapq og triks for max-heap
Bruk heapq.heappush/heappop, neger verdier for å simulere en max-heap, og bruk heapq.nlargest/nsmallest til raske top-k-spørringer.
Pythons heapq og triks for max-heap er en gratis leksjon i DSA Interview Prep på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i DSA Interview Prep, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i DSA Interview Prep inneholder totalt 4 leksjoner.
Oversikt over Pythons heapq-modul
Pythons heapq-modul tilbyr en min-heap implementert oppå en vanlig Python-liste. I motsetning til en dedikert heap-klasse endrer heapq eksisterende lister direkte. Modulens funksjoner er: heapify for å bygge en heap på O(n), heappush for å legge til et element på O(log n), heappop for å fjerne minimumselementet på O(log n), og heappushpop / heapreplace for kombinert effektivitet.
import heapq
# heapq operates on plain Python lists
heap = []
heapq.heappush(heap, 5)
heapq.heappush(heap, 2)
heapq.heappush(heap, 8)
heapq.heappush(heap, 1)
print('Heap array:', heap) # internal array (not sorted!)
print('Peek min:', heap[0]) # O(1) min access
print('Pop min:', heapq.heappop(heap)) # 1
print('Next min:', heap[0]) # 2
# heapify: turn any list into a heap in O(n)
data = [9, 4, 7, 1, 3, 6, 2]
heapq.heapify(data)
print('Heapified:', data, '| min:', data[0])Maks-heap ved å negere verdier
Pythons heapq tilbyr bare en min-heap. For å simulere en maks-heap negerer De alle verdier før de legges inn, og negerer dem på nytt når de tas ut. Dette fungerer fordi heapen ordner etter de lagrede verdiene, og negasjon snur rekkefølgen. Husk alltid å negere på begge sider: før innsetting og etter uttak. Å glemme ett av trinnene er en vanlig feil i intervjuer.
import heapq
max_heap = []
for val in [5, 1, 8, 3, 9, 2]:
heapq.heappush(max_heap, -val) # negate on push
print('Max-heap internal:', max_heap) # all negated
# Pop in descending order:
results = []
while max_heap:
results.append(-heapq.heappop(max_heap)) # negate on pop
print('Sorted descending:', results) # [9, 8, 5, 3, 2, 1]
# Common pattern: top-k largest
data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
k = 3
heap = []
for x in data:
heapq.heappush(heap, -x)
print('Top', k, ':', [-heapq.heappop(heap) for _ in range(k)])heapq.nlargest og nsmallest
heapq.nlargest(k, iterable) og heapq.nsmallest(k, iterable) returnerer de k største eller minste elementene. De har kompleksitet O(n log k) — mer effektivt enn full sortering (O(n log n)) når k er mye mindre enn n. Internt bruker de en heap med størrelse k. Når k er nær n, går Python over til full sortering. Bruk disse til engangsforespørsler om topp-k-elementer uten å vedlikeholde en permanent heap.
import heapq
data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 7]
# Top 3 largest:
print(heapq.nlargest(3, data)) # [9, 8, 7]
# Top 3 smallest:
print(heapq.nsmallest(3, data)) # [1, 1, 2]
# With a key function:
words = ['banana', 'apple', 'cherry', 'date', 'elderberry']
print(heapq.nlargest(2, words, key=len)) # ['elderberry', 'banana']
print(heapq.nsmallest(2, words, key=len)) # ['date', 'apple']
# Note: when k ~ n, use sorted() instead:
# sorted(data)[-k:] or sorted(data, reverse=True)[:k]Heap med tupler for komplekse nøkler
Når heap-elementer trenger en tilpasset sammenligningsnøkkel, lagrer De dem som tupler (priority, data). Pythons heapq sammenligner tupler element for element, så den sammenligner først prioritetene. Hvis prioritetene er like, sammenlignes det andre elementet — dette kan føre til feil hvis dataene ikke kan sammenlignes. Det tryggeste mønsteret er å ta med en unik teller som tie-breaker, slik at dataelementer aldri sammenlignes direkte.
import heapq
import itertools
# Pattern: (priority, counter, item)
# Counter ensures unique tiebreaker, avoids comparing items
counter = itertools.count()
heap = []
def push_task(priority, task):
heapq.heappush(heap, (priority, next(counter), task))
push_task(3, 'low priority task')
push_task(1, 'high priority task')
push_task(2, 'medium priority task')
push_task(1, 'another high priority')
while heap:
pri, cnt, task = heapq.heappop(heap)
print(f'P{pri}: {task}')
# Output in priority order: P1, P1, P2, P3heapq.merge: Fletting av sorterte itererbare objekter
heapq.merge(*iterables) slår flere sorterte itererbare objekter sammen fortløpende til ett sortert resultat uten å laste alle dataene inn i minnet. Dette tilsvarer en k-veis fletting ved hjelp av en min-heap med størrelse k og brukes i algoritmer for ekstern sortering. Funksjonen returnerer en iterator, så elementene produseres ett av gangen — ideelt for store datasett eller strømmescenarioer.
import heapq
# Merge multiple sorted lists efficiently
sorted_lists = [
[1, 5, 9],
[2, 6, 8],
[3, 4, 7]
]
# heapq.merge takes sorted iterables and returns a merged sorted iterator
merged = list(heapq.merge(*sorted_lists))
print('Merged:', merged) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# The k-way merge manually (educational version):
def merge_k_sorted(lists):
heap = []
for i, lst in enumerate(lists):
if lst:
heapq.heappush(heap, (lst[0], i, 0))
result = []
while heap:
val, list_idx, elem_idx = heapq.heappop(heap)
result.append(val)
if elem_idx + 1 < len(lists[list_idx]):
heapq.heappush(heap, (lists[list_idx][elem_idx+1], list_idx, elem_idx+1))
return result
print('Manual k-way:', merge_k_sorted(sorted_lists))Mønster for lazy deletion i heap-er
Når De må fjerne vilkårlige elementer fra en heap, men ikke kjenner indeksen, bruker De lazy deletion: Marker elementer som slettet i et separat sett, og hopp deretter over dem ved uttak. Dette har amortisert kompleksitet O(log n) og unngår kompleksiteten ved å spore indekser. Det er standardmetoden i Dijkstras algoritme med dupliserte oppføringer og simuleringer av oppgaveplanleggere.
import heapq
class LazyHeap:
def __init__(self):
self._heap = []
self._removed = set()
def push(self, task):
heapq.heappush(self._heap, task)
def remove(self, task):
self._removed.add(task) # mark as removed
def pop(self):
while self._heap:
task = heapq.heappop(self._heap)
if task not in self._removed:
return task
return None
lh = LazyHeap()
for t in [5, 1, 8, 3, 2]:
lh.push(t)
lh.remove(1) # 'delete' 1 lazily
lh.remove(8) # 'delete' 8 lazily
results = [lh.pop() for _ in range(3)]
print(results) # [2, 3, 5] -- 1 and 8 skippedDet k-te største elementet i en datastrøm
Det k-te største elementet i en datastrøm (LeetCode #703) vedlikeholder en min-heap med størrelse k. Roten i heapen er alltid det k-te største elementet som er sett så langt. Når et nytt tall kommer: legg det inn, og hvis heapen blir større enn k, ta ut minimumet. Roten er alltid det k-te største fordi det finnes nøyaktig k-1 elementer i heapen som er større enn det.
import heapq
class KthLargest:
def __init__(self, k, nums):
self.k = k
self.heap = []
for num in nums:
self.add(num)
def add(self, val):
heapq.heappush(self.heap, val)
if len(self.heap) > self.k:
heapq.heappop(self.heap) # remove smallest
return self.heap[0] # kth largest = root of min-heap
# k=3, initial=[4,5,8,2]
kl = KthLargest(3, [4, 5, 8, 2])
print(kl.add(3)) # 4 (top 3: 8,5,4 -- kth=4)
print(kl.add(5)) # 5 (top 3: 8,5,5 -- kth=5)
print(kl.add(10)) # 5 (top 3: 10,8,5 -- kth=5)
print(kl.add(9)) # 8 (top 3: 10,9,8 -- kth=8)Finn k par med de minste summene
Finn k par med de minste summene (LeetCode #373) bruker en min-heap til å generere par i sortert rekkefølge. Start med alle parene (nums1[0], nums2[j]) for hver j. Ta ut minimumet, og for det uttatte paret (nums1[i], nums2[j]) legger De inn (nums1[i+1], nums2[j]) — den neste kandidaten fra samme nums2-kolonne. Dette er et vanlig mønster for generering av sorterte par eller produkter med en heap.
import heapq
def k_smallest_pairs(nums1, nums2, k):
if not nums1 or not nums2:
return []
heap = []
# Initialize with pairs (nums1[0], nums2[j])
for j in range(min(k, len(nums2))):
heapq.heappush(heap, (nums1[0] + nums2[j], 0, j))
result = []
while heap and len(result) < k:
total, i, j = heapq.heappop(heap)
result.append([nums1[i], nums2[j]])
if i + 1 < len(nums1):
heapq.heappush(heap, (nums1[i+1] + nums2[j], i+1, j))
return result
print(k_smallest_pairs([1,7,11], [2,4,6], 3))
# [[1,2], [1,4], [1,6]]Oppgaveplanlegger med en maks-heap
Oppgaveplanlegger (LeetCode #621) ber Dem finne den korteste tiden for å planlegge n oppgaver med en avkjølingsperiode på n intervaller mellom like oppgaver. Bruk en maks-heap over oppgavefrekvenser: ved hvert tidssteg velger De den tilgjengelige oppgaven med høyest frekvens, reduserer antallet og setter den i avkjøling. Behandle k=n+1 oppgaver per syklus (eller fyll resten med inaktiv tid). Denne grådige tilnærmingen med en maks-heap gir det optimale svaret.
import heapq
from collections import Counter
def least_interval(tasks, n):
freq = Counter(tasks)
heap = [-f for f in freq.values()] # max-heap (negated)
heapq.heapify(heap)
time = 0
while heap:
cycle = n + 1
temp = []
for _ in range(cycle):
if heap:
temp.append(heapq.heappop(heap))
for f in temp:
if f + 1 < 0: # still tasks remaining
heapq.heappush(heap, f + 1)
# Add full cycle or remaining tasks if queue empty
time += cycle if heap else len(temp)
return time
print(least_interval(['A','A','A','B','B','B'], 2)) # 8
print(least_interval(['A','A','A','B','B','B'], 0)) # 6Heap i Dijkstras algoritme
Prioritetskøen i Dijkstras algoritme implementeres med en min-heap. Lagre tupler (distance, node) og behandle alltid den nærmeste ubesøkte noden først. Når De tar ut en node med en avstand som er større enn den korteste stien som for øyeblikket er kjent (en foreldet oppføring fra lazy deletion), hopper De over den. Dette eliminerer behovet for en decrease-key-operasjon og holder implementeringen enkel, samtidig som kompleksiteten O((V + E) log V) opprettholdes.
import heapq
def dijkstra(graph, start):
dist = {node: float('inf') for node in graph}
dist[start] = 0
heap = [(0, start)] # (distance, node)
while heap:
d, u = heapq.heappop(heap)
if d > dist[u]: # stale entry, skip
continue
for v, w in graph[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
heapq.heappush(heap, (dist[v], v))
return dist
graph = {
'A': [('B', 4), ('C', 1)],
'B': [('D', 1)],
'C': [('B', 2), ('D', 5)],
'D': []
}
print(dijkstra(graph, 'A')) # {'A':0,'B':3,'C':1,'D':4}Omorganiser en streng med en maks-heap
Omorganiser en streng (LeetCode #767) ber Dem omorganisere en streng slik at ingen to nabotegn er like. Bruk en maks-heap med (-frequency, char). Ved hvert trinn tar De ut det mest frekvente tegnet. Hvis det forrige tegnet er det samme som det mest frekvente, tar De i stedet ut det nest mest frekvente. Denne grådige tilnærmingen sørger for at det mest begrensede tegnet plasseres så tidlig som mulig.
import heapq
from collections import Counter
def reorganize_string(s):
freq = Counter(s)
heap = [(-f, c) for c, f in freq.items()]
heapq.heapify(heap)
result = []
prev_freq, prev_char = 0, ''
while heap:
freq, char = heapq.heappop(heap)
result.append(char)
# Push back the previous character if still remaining
if prev_freq < 0:
heapq.heappush(heap, (prev_freq, prev_char))
prev_freq, prev_char = freq + 1, char # decrement freq (less negative)
result_str = ''.join(result)
# Verify no adjacent duplicates
return result_str if len(result_str) == len(s) else ''
print(reorganize_string('aab')) # 'aba'
print(reorganize_string('aaab')) # '' (impossible)Rask sjekk
Test forståelsen Deres av konseptene fra Data Structures & Algorithms — Coding Interview Prep i denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen lærte De: Pythons heapq-modul-API, inkludert heapify, heappush, heappop, nlargest, nsmallest og merge, simulering av maks-heap ved å negere verdier, samt vanlige heap-mønstre i intervjuer, blant annet topp-k-strømming, det k-te største elementet i en datastrøm, oppgaveplanleggeren og Dijkstra. Neste gang tar vi for oss median fra en datastrøm og k-veis fletting.
Lær deg Python med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Pythons heapq og triks for max-heap» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien DSA Interview Prep, inkludert «Pythons heapq og triks for max-heap», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i DSA Interview Prep inneholder totalt 4 leksjoner.
Hva lærer jeg i «Pythons heapq og triks for max-heap»?
Bruk heapq.heappush/heappop, neger verdier for å simulere en max-heap, og bruk heapq.nlargest/nsmallest til raske top-k-spørringer. Du øver på DSA Interview Prep med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med DSA Interview Prep?
Ingen tidligere erfaring er nødvendig. DSA Interview Prep på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Pythons heapq og triks for max-heap»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne DSA Interview Prep-leksjonen?
Ja. Alle DSA Interview Prep-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Heap-egenskapen og arrayrepresentasjon
- Heapify, push og pop fra grunnen av
- Pythons heapq og triks for max-heap
- Median fra datastrøm og k-veis fletting