Find the K-Sum of an Array

kth largest of all subsequence sums — flip signs of negatives, sort, then BFS through pop-or-replace via a min-heap.

Hard
Time O((n + k) log (n + k)) Space O(n + k)
LeetCode
6 min read
top-k heaps

Problem#

Return the kth largest sum over all 2^n subsequences of nums.

Examples#

  • nums = [2,4,-2], k = 52

Constraints#

  • 1 <= n <= 10^5, 1 <= k <= min(2000, 2^n).

Hints#

Hint 1
Largest sum is sum of all positives. Reduce others to “minimum loss” from that maximum.

Approach#

  1. Compute maxSum = sum of positives. Replace each nums[i] with |nums[i]|. The kth largest sum equals maxSum - (k−1)th smallest loss, where a loss is the sum of any subset of the absolute values.
  2. Sort abs(nums) ascending. Min-heap of (loss, index) starting at (0, 0). To generate next smallest loss, pop top (l, i); push (l + abs[i], i+1) (add next element) and (l + abs[i] - abs[i-1], i+1) (swap current for next).

Solution#

Find the K-Sum
class Solution {
public:
long long kSum(vector<int>& nums, int k) {
long long maxSum = 0;
for (int& x : nums) {
if (x > 0) maxSum += x;
else x = -x;
}
sort(nums.begin(), nums.end());
priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;
pq.push({0, 0});
long long loss = 0;
for (int i = 0; i < k - 1; ++i) {
auto [l, idx] = pq.top(); pq.pop();
loss = l;
if (idx < (int)nums.size()) {
pq.push({l + nums[idx], idx + 1});
if (idx > 0) pq.push({l + nums[idx] - nums[idx - 1], idx + 1});
}
}
return maxSum - loss;
}
};

Editorial#

The folklore trick: turn the problem into finding the (k-1)th smallest subset sum of the absolute values. Two children per heap-pop (extend with next, or swap with next) systematically explore every subset in sum-ascending order without duplicates.

Complexity#

  • Time: O((n + k) log (n + k)).
  • Space: O(n + k).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.