Median of K Sliding Windows (Extended Practice)
Advertisement
Problem
Apply the sliding window median pattern to a stream: maintain median as elements are added and removed.
This reinforces the lazy-deletion two-heap technique which is critical for hard interview problems.
Key Template — Lazy Deletion Two Heaps
# Python — reusable template
import heapq
from collections import defaultdict
class DualHeap:
def __init__(self, k):
self.k = k
self.lo = [] # max-heap (negate)
self.hi = [] # min-heap
self.lo_size = 0
self.hi_size = 0
self.trash = defaultdict(int)
def _prune(self, heap):
while heap and self.trash[abs(heap[0])] > 0:
self.trash[abs(heap[0])] -= 1
heapq.heappop(heap)
def add(self, num):
if not self.lo or -self.lo[0] >= num:
heapq.heappush(self.lo, -num)
self.lo_size += 1
else:
heapq.heappush(self.hi, num)
self.hi_size += 1
self._balance()
def remove(self, num):
self.trash[num] += 1
if num <= -self.lo[0]:
self.lo_size -= 1
else:
self.hi_size -= 1
self._balance()
def _balance(self):
while self.lo_size > self.hi_size + 1:
self._prune(self.lo)
v = -heapq.heappop(self.lo)
self.lo_size -= 1
heapq.heappush(self.hi, v)
self.hi_size += 1
self._prune(self.hi)
while self.hi_size > self.lo_size:
self._prune(self.hi)
v = heapq.heappop(self.hi)
self.hi_size -= 1
heapq.heappush(self.lo, -v)
self.lo_size += 1
self._prune(self.lo)
def median(self):
self._prune(self.lo)
self._prune(self.hi)
if self.k % 2 == 1:
return float(-self.lo[0])
return (-self.lo[0] + self.hi[0]) / 2.0
// C++ template — see sliding window median problem
// Key insight: Track lo_valid_size and hi_valid_size separately from heap sizes
// Java — similar lazy deletion with TreeMap for O(log n) operations:
class Solution {
TreeMap<Integer, Integer> lo, hi; // value -> count
int loSize, hiSize;
// add/remove manipulate sizes + lazy prune on median access
}
// JavaScript — use SortedList equivalent (binary search insertion)
// Performance: O(k) per operation with array, O(log k) with proper BST
When to Use
- Sliding window median (fixed k)
- Dynamic median with arbitrary add/remove
- Any problem needing order statistics on a dynamic set
Complexity
- add/remove: O(log n) amortized
- median: O(1) with pruning
Advertisement