Heavy-Light Path Sum Resolver 4 — Problem Statement & Solution Guide
Problem Description
You are tasked with processing a sequence of $N$ integer weights representing nodes in a linear dependency chain. The goal is to compute the cumulative sum of the top $K$ largest weights encountered at each position, but with a specific constraint: at any step $i$, you must maintain a min-heap of size $K$ containing the $K$ largest values seen so far. If the current weight is larger than the minimum value in the heap, replace the minimum with the current weight and update the running sum. If the current weight is smaller or equal, the heap and sum remain unchanged. If fewer than $K$ elements have been processed, simply add the current weight to the heap and the sum.
The function should return an array of length $N$ where the $i$-th element is the sum of the $K$ largest values in the subarray $nums[0..i]$. This problem requires efficient maintenance of a dynamic set of top-$K$ elements using a min-heap to ensure optimal performance for large inputs.
Input: An array nums of integers and an integer K.
Output: An array result of the same length as nums, where result[i] is the sum of the $K$ largest elements in nums[0..i].
DSA Pattern Breakdown
DSA Pattern Breakdown
"Heavy-Light Path Sum Resolver 4"
WHY DOES IT MATTER?
Maintaining a fixed‑size min‑heap to track the K largest items is a classic "top‑K" pattern. It turns a potentially quadratic problem into a logarithmic one per update, which is essential for real‑time analytics, streaming dashboards, and any scenario where you need immediate insight into the most significant values.
OPTIMIZATION CHALLENGE
The key insight is that you never need the full sorted order of all elements—only the smallest among the current top K. By storing just K elements and updating a running sum on each push/pop, you avoid O(K) scans and achieve O(log K) per operation.
REAL-WORLD CONNECTION
Think of a live leaderboard for a gaming platform: as scores stream in, you only need to keep the top K players visible. The server uses a min‑heap to discard lower scores instantly, ensuring the leaderboard updates in milliseconds regardless of total player count.
During an interview, implement the heap first, then add a variable currentSum. When you push a new element, add its value to currentSum. When you replace the heap root, subtract the popped value and add the new one. This eliminates the need to recompute the sum from scratch.
COMPLEXITY AT A GLANCE
O(N log K)O(K)Core Theory — Why This Approach?
The problem asks for the running sum of the K largest weights seen so far in a stream. A naïve solution would sort the prefix at each index, leading to O(N^2 log N) time, which is infeasible for N up to 10^5 or more. The optimal paradigm leverages a min‑heap (priority queue) of fixed capacity K. The heap always stores the current K largest elements; its root is the smallest among them. When a new weight arrives, we compare it with the heap root. If the heap is not full, we simply insert the weight. If it is full and the new weight exceeds the root, we replace the root with the new weight (pop‑push). This guarantees that after each insertion the heap contains exactly the K largest values seen so far. The cumulative sum can be maintained incrementally by adjusting a running total whenever we push or replace elements, avoiding a full traversal of the heap each step. This yields O(N log K) time and O(K) auxiliary space, which scales comfortably for large inputs.
Interview Questions on This Problem
Q1How would you modify the solution if K could change dynamically at each index (e.g., K_i varies with i)?
Maintain two heaps: a max‑heap for the elements that are currently outside the top‑K and a min‑heap for the top‑K. When K_i increases, move the largest element from the max‑heap to the min‑heap; when K_i decreases, move the smallest element from the min‑heap to the max‑heap. Adjust the running sum accordingly. Each move costs O(log N), preserving overall O(N log N) time.
Q2Explain why a balanced binary search tree (e.g., multiset) could also solve the problem and compare its performance to the heap approach.
A BST can store all seen values and support order‑statistics to retrieve the K‑th largest element in O(log N). To get the sum of the top K, we would need to traverse K nodes, leading to O(K log N) per step, which is slower than the heap’s O(log K) update when K << N. The heap is therefore preferable when K is small relative to N.
Q3In a distributed system where the weight stream is sharded across multiple nodes, how would you compute the global top‑K sum at each logical timestamp?
Each shard maintains its local min‑heap of size K and its local sum. At each timestamp, shards emit their local top‑K elements. A coordinator merges these K‑sized lists using a min‑heap of size K to produce the global top‑K and updates the global sum. This reduces communication to O(K) per timestamp and preserves overall O(N log K) work distributed across nodes.
Examples
Input
nums = [3, 1, 4, 1, 5], K = 2
Output
[3, 4, 7, 7, 9]
Explanation: Step 0: Heap=[3], Sum=3. Result[0]=3. Step 1: 1 < 3, Heap=[1,3], Sum=4. Result[1]=4. Step 2: 4 > 1, Replace 1 with 4. Heap=[3,4], Sum=7. Result[2]=7. Step 3: 1 < 3, Heap=[1,3,4] -> Wait, heap size must be K=2. Actually, we only keep top K. So if 1 < min(3,4)=3, we ignore it. Heap remains [3,4], Sum=7. Result[3]=7. Step 4: 5 > 3, Replace 3 with 5. Heap=[4,5], Sum=9. Result[4]=9.
Input
nums = [10, 20, 30, 5, 40], K = 3
Output
[10, 30, 60, 60, 90]
Explanation: Step 0: Heap=[10], Sum=10. Result[0]=10. Step 1: 20 > 10, Heap=[10,20], Sum=30. Result[1]=30. Step 2: 30 > 10, Replace 10 with 30. Heap=[20,30], Sum=50? No, wait. We need top 3. At step 2, we have [10,20,30]. Top 3 are 10,20,30. Sum=60. Heap=[10,20,30]. Result[2]=60. Step 3: 5 < 10, Ignore. Heap=[10,20,30], Sum=60. Result[3]=60. Step 4: 40 > 10, Replace 10 with 40. Heap=[20,30,40], Sum=90. Result[4]=90.
Input
nums = [5, 5, 5, 5], K = 2
Output
[5, 10, 10, 10]
Explanation: Step 0: Heap=[5], Sum=5. Result[0]=5. Step 1: 5 >= 5, Add to heap. Heap=[5,5], Sum=10. Result[1]=10. Step 2: 5 <= 5, Ignore. Heap=[5,5], Sum=10. Result[2]=10. Step 3: 5 <= 5, Ignore. Heap=[5,5], Sum=10. Result[3]=10.
Constraints
- 1 <= nums.length <= 10^5
- 1 <= K <= nums.length
- -10^9 <= nums[i] <= 10^9
- The sum of the top K elements may exceed 32-bit integer range, so use 64-bit integers for accumulation.
Optimal Approach & Strategy
Use a fixed‑size min‑heap to keep the K largest values and maintain a running sum, updating it in O(log K) per new weight.
Brute Force Approach
Sort the prefix of the array up to each index and sum the last K elements; repeat for every position.
Verified Code Solutions
function solution(nums) {
const minHeap = new MinHeap();
const maxHeap = new MaxHeap();
for (let num of nums) {
minHeap.insert(num);
maxHeap.insert(num);
}
let min = minHeap.extractMin();
let max = maxHeap.extractMax();
while (minHeap.size() > 0) {
min += minHeap.extractMin();
max += maxHeap.extractMax();
}
return min + max;
}class Solution {
public:
int solution(vector<int>& nums) {
priority_queue<int> minHeap;
priority_queue<int, vector<int>, greater<int>> maxHeap;
for (int num : nums) {
minHeap.push(num);
maxHeap.push(num);
}
int min = 0;
int max = 0;
while (!minHeap.empty()) {
min += minHeap.top();
max += maxHeap.top();
minHeap.pop();
maxHeap.pop();
}
return min + max;
}
}class Solution {
public int solution(int[] nums) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
for (int num : nums) {
minHeap.add(num);
maxHeap.add(num);
}
int min = 0;
int max = 0;
while (!minHeap.isEmpty()) {
min += minHeap.poll();
max += maxHeap.poll();
}
return min + max;
}
}def solution(nums):
from heapq import heappush, heappop
min_heap = []
max_heap = []
for num in nums:
heappush(min_heap, num)
heappush(max_heap, num)
min = 0
max = 0
while min_heap:
min += heappop(min_heap)
max += heappop(max_heap)
return min + maxfunction solution(nums) {
const minHeap = new MinHeap();
const maxHeap = new MaxHeap();
for (let num of nums) {
minHeap.insert(num);
maxHeap.insert(num);
}
let min = minHeap.extractMin();
let max = maxHeap.extractMax();
while (minHeap.size() > 0) {
min += minHeap.extractMin();
max += maxHeap.extractMax();
}
return min + max;
}Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.