You are given an integer array nums
and a positive integer k
. You can choose any subsequence of the array and sum all of its elements together.
We define the K-Sum of the array as the kth
largest subsequence sum that can be obtained (not necessarily distinct).
Return the K-Sum of the array.
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
Note that the empty subsequence is considered to have a sum of 0
.
Example 1:
Input: nums = [2,4,-2], k = 5 Output: 2 Explanation: All the possible subsequence sums that we can obtain are the following sorted in decreasing order: - 6, 4, 4, 2, 2, 0, 0, -2. The 5-Sum of the array is 2.
Example 2:
Input: nums = [1,-2,3,4,-10,12], k = 16 Output: 10 Explanation: The 16-Sum of the array is 10.
Constraints:
n == nums.length
1 <= n <= 105
-109 <= nums[i] <= 109
1 <= k <= min(2000, 2n)
This problem asks to find the k-th largest subsequence sum of a given integer array. A brute-force approach would generate all possible subsequence sums, sort them, and return the k-th largest. However, this is computationally expensive, with a time complexity exponential to the array size. The optimal solution leverages a min-heap (priority queue) to efficiently find the k-th largest sum.
Handle Negative Numbers: The algorithm simplifies by converting all negative numbers to their positive counterparts. The maximum subsequence sum (the sum of all positive numbers) is calculated and stored in mx
. This step reduces the problem to finding the k-th smallest subsequence sum using the transformed positive numbers, because any subsequence sum from the original array is a difference between mx
and a specific subsequence sum of the transformed positive numbers.
Sorting: The transformed positive numbers are sorted in ascending order. This enables an efficient way to generate subsequence sums in an organized manner.
Min-Heap: A min-heap is used to store potential subsequence sums. Each element in the heap is a pair (sum, index)
, where sum
is the current subsequence sum and index
is the index of the next number to consider for extending the subsequence.
Iterative Refinement: The algorithm iteratively refines the heap. In each iteration, the smallest sum (top of the heap) is extracted. Two new sums are then generated and pushed onto the heap:
K-th Smallest: This process continues until k-1
elements have been extracted from the heap. The remaining smallest element in the heap represents the k-th smallest sum using the transformed array. The k-th largest sum in the original array is calculated as mx - kth_smallest_sum
.
Time Complexity: The dominant operations are sorting the array (O(n log n)
) and heap operations (O(k log k)
). The overall time complexity is O(n log n + k log k).
Space Complexity: The space complexity is determined mainly by the size of the heap and the sorted array, which are both proportional to the array size. Therefore, the space complexity is O(n).
import heapq
class Solution:
def kSum(self, nums: List[int], k: int) -> int:
mx = 0
for i, x in enumerate(nums):
if x > 0:
mx += x
else:
nums[i] = -x # Convert negative numbers to positive
nums.sort()
h = [(0, 0)] # Initialize min-heap with (sum, index) = (0, 0)
for _ in range(k - 1):
s, i = heapq.heappop(h)
if i < len(nums):
heapq.heappush(h, (s + nums[i], i + 1)) # Add next number
if i:
heapq.heappush(h, (s + nums[i] - nums[i - 1], i + 1)) # Skip next number
return mx - h[0][0] # kth largest sum = mx - kth smallest sum
The Java, C++, and Go implementations follow a similar structure, adapting the data structures and syntax of their respective languages. The core algorithmic logic remains the same across all implementations.