Heaps (Priority Queues)
Introduction
A Heap is a specialized tree-based data structure that satisfies the heap property: the parent node is always smaller (Min-Heap) or larger (Max-Heap) than its children.
This guarantees that the root node is always the minimum or maximum element.
How to Recognize It
Use a Heap when: - The problem asks for the Top K, Kth Largest, or Kth Smallest elements. - You need to repeatedly extract the minimum/maximum element from a dynamic dataset. - You are merging \(K\) sorted arrays. - You are implementing Dijkstra's algorithm for shortest paths in weighted graphs.
The Pythonic Implementation: heapq
In Python, a heap is simply a standard list that is manipulated using the heapq module.
Python only provides a Min-Heap natively. The smallest element is always at index 0.
import heapq
nums = [5, 1, 9, 3]
# 1. Transform a list into a Min-Heap in-place (O(N))
heapq.heapify(nums)
print(nums[0]) # 1 (The minimum element)
# 2. Push an element (O(log N))
heapq.heappush(nums, 2)
# 3. Pop the smallest element (O(log N))
smallest = heapq.heappop(nums)
print(smallest) # 1
Pattern 1: The Top K Elements
To find the Top \(K\) largest elements, maintain a Min-Heap of size exactly \(K\).
As you iterate through the data, push elements onto the heap. If the heap grows larger than \(K\), pop the smallest element. At the end, the heap will contain exactly the \(K\) largest elements.
import heapq
def find_k_largest(nums, k):
min_heap = []
for num in nums:
heapq.heappush(min_heap, num)
# If heap is too large, drop the smallest element
if len(min_heap) > k:
heapq.heappop(min_heap)
# The heap now contains the K largest elements
return min_heap
Pattern 2: Max-Heaps in Python
Because heapq only provides a Min-Heap, if you need a Max-Heap, you must negate all the numbers before pushing them, and negate them again when popping.
import heapq
def max_heap_example(nums):
max_heap = []
for num in nums:
# Push negative value
heapq.heappush(max_heap, -num)
# Pop and negate to get original value
largest = -heapq.heappop(max_heap)
return largest
(-priority, item), ensure the item is comparable in case priorities tie).
Time and Space Complexity
- Heapify: \(O(N)\)
- Push: \(O(\log N)\)
- Pop: \(O(\log N)\)
- Peek Minimum: \(O(1)\) (using
heap[0])
Summary
- A Heap instantly provides the Min/Max element.
- Python's
heapquses standard lists and only provides a Min-Heap. - For a Max-Heap, insert
-value. - Use a Min-Heap of size \(K\) to solve "Top K Largest" problems in \(O(N \log K)\) time.