Practice
import heapq
class KthLargest:
def __init__(self, k: int, nums: list[int]):
self.k = k
self.heap = nums
heapq.heapify(self.heap)
while len(self.heap) > k:
heapq.heappop(self.heap)
def add(self, val: int) -> int:
if len(self.heap) < self.k:
heapq.heappush(self.heap, val)
elif val > self.heap[0]:
heapq.heapreplace(self.heap, val)
return self.heap[0]
kthLargest = KthLargest(3, [4, 5, 8, 2])
print(kthLargest.add(3))
print(kthLargest.add(5))
print(kthLargest.add(10))
print(kthLargest.add(9))
print(kthLargest.add(4))
Solution
Step 1: Trace heap initialization
Initial nums = [4,5,8,2], heapified and trimmed to size k=3: heap becomes [4,5,8] after popping 2.Step 2: Trace add calls and heap updates
add(3): 3 < 4 (heap[0]), no replace, return 4 add(5): 5 > 4, replace 4 with 5, heap now [5,5,8], return 5 add(10): 10 > 5, replace 5 with 10, heap now [5,10,8], return 5 add(9): 9 > 5, replace 5 with 9, heap now [8,10,9], return 8 add(4): 4 < 8, no replace, return 8Final Answer:
Option C -> Option CQuick Check:
Last add returns 8 as kth largest element [OK]
- Off-by-one errors in heap size
- Replacing when val <= heap[0]
- Misunderstanding heap root meaning
Solution
Step 1: Identify heap size and operations
The heap size is fixed at k, independent of stream length n. Each add involves either a push or a replace operation on the heap.Step 2: Analyze complexity of heap operations
Heap push or replace operations take O(log k) time because the heap has size k. Accessing the root is O(1), but add involves heapify steps.Final Answer:
Option D -> Option DQuick Check:
Heap operations depend on k, not n, so O(log k) per add [OK]
- Confusing n with k in complexity
- Assuming linear scan of heap
- Ignoring heapify cost
popK(k) that removes and returns the top k most frequent elements in order, breaking ties by recency. Which modification to the optimal heap-based approach correctly supports this operation efficiently?Solution
Step 1: Understand popK(k) requirements
We must pop the top k elements by frequency and recency order, updating frequencies after each pop.Step 2: Evaluate modifications
Performkconsecutivepop()calls on the heap, updating frequencies after each pop. This performs k pops sequentially, each O(log n), correctly updating frequencies and maintaining heap invariants. Options A, B, and D either complicate the data structure or lose efficiency and correctness.Final Answer:
Option A -> Option AQuick Check:
Sequential pops maintain correctness and efficiency [OK]
- Trying to pop multiple elements at once without updating frequencies
- Using complex data structures that break heap invariants
Solution
Step 1: Understand duplicates impact
Duplicates must be treated as distinct points; Quickselect partitions by distance and does not rely on uniqueness.Step 2: Modify partition to handle duplicates correctly
Partition logic remains the same; all points, including duplicates, are compared and placed correctly without skipping.Final Answer:
Option D -> Option DQuick Check:
Quickselect handles duplicates naturally if partitioning is correct [OK]
- Using min heap instead of max heap
- Removing duplicates before selection
- Sorting all points unnecessarily
Solution
Step 1: Understand infinite reuse impact
Infinite reuse means frequency counts are not fixed; problem becomes combinatorial.Step 2: Recognize problem class change
Top k frequent words with unlimited reuse resembles knapsack or coin change, not simple frequency counting.Step 3: Bucket sort no longer applies
Bucket sort relies on fixed frequencies; dynamic programming or other combinatorial methods are needed.Final Answer:
Option A -> Option AQuick Check:
Infinite reuse breaks frequency counting assumptions [OK]
- Trying to reuse bucket sort with infinite counts
- Ignoring combinatorial explosion
- Assuming heap approach suffices
