Heaps (Min-Heap, Max-Heap)
Mind Map Summary
- Topic: Heaps (Min-Heap, Max-Heap)
- Properties:
- Heap: A complete binary tree where each node is smaller (Min-Heap) or larger (Max-Heap) than its children.
- Implementation: Typically implemented using an array.
- Use Cases:
- Priority Queues: Heaps are the ideal data structure for implementing priority queues.
- Finding K-th Smallest/Largest Element: Heaps can be used to efficiently find the k-th smallest or largest element in an array.
Practice Exercise
Implement a Min-Heap from scratch with insert
and extractMin
operations. Use a Min-Heap to find the ‘K’ largest elements in an array. Find the median from a data stream.
Answer
1. Implement a Min-Heap:
public class MinHeap {
private List<int> heap = new List<int>();
public void Insert(int val) {
heap.Add(val);
int i = heap.Count - 1;
while (i > 0 && heap[i] < heap[(i - 1) / 2]) {
Swap(i, (i - 1) / 2);
i = (i - 1) / 2;
}
}
public int ExtractMin() {
if (heap.Count == 0) throw new InvalidOperationException();
int min = heap[0];
heap[0] = heap[heap.Count - 1];
heap.RemoveAt(heap.Count - 1);
Heapify(0);
return min;
}
private void Heapify(int i) {
int left = 2 * i + 1;
int right = 2 * i + 2;
int smallest = i;
if (left < heap.Count && heap[left] < heap[smallest]) smallest = left;
if (right < heap.Count && heap[right] < heap[smallest]) smallest = right;
if (smallest != i) {
Swap(i, smallest);
Heapify(smallest);
}
}
private void Swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}
2. Find the K Largest Elements in an Array:
public int FindKthLargest(int[] nums, int k) {
var minHeap = new PriorityQueue<int, int>();
foreach (int num in nums) {
minHeap.Enqueue(num, num);
if (minHeap.Count > k) {
minHeap.Dequeue();
}
}
return minHeap.Peek();
}
3. Find Median from Data Stream:
public class MedianFinder {
private PriorityQueue<int, int> minHeap = new PriorityQueue<int, int>();
private PriorityQueue<int, int> maxHeap = new PriorityQueue<int, int>(Comparer<int>.Create((a, b) => b.CompareTo(a)));
public void AddNum(int num) {
maxHeap.Enqueue(num, num);
minHeap.Enqueue(maxHeap.Peek(), maxHeap.Peek());
maxHeap.Dequeue();
if (minHeap.Count > maxHeap.Count) {
maxHeap.Enqueue(minHeap.Peek(), minHeap.Peek());
minHeap.Dequeue();
}
}
public double FindMedian() {
if (maxHeap.Count > minHeap.Count) {
return maxHeap.Peek();
} else {
return (maxHeap.Peek() + minHeap.Peek()) / 2.0;
}
}
}