1918. Kth Smallest Subarray Sum π
Description
Given an integer array nums
of length n
and an integer k
, return the kth
smallest subarray sum.
A subarray is defined as a non-empty contiguous sequence of elements in an array. A subarray sum is the sum of all elements in the subarray.
Example 1:
Input: nums = [2,1,3], k = 4 Output: 3 Explanation: The subarrays of [2,1,3] are: - [2] with sum 2 - [1] with sum 1 - [3] with sum 3 - [2,1] with sum 3 - [1,3] with sum 4 - [2,1,3] with sum 6 Ordering the sums from smallest to largest gives 1, 2, 3, 3, 4, 6. The 4th smallest is 3.
Example 2:
Input: nums = [3,3,5,5], k = 7 Output: 10 Explanation: The subarrays of [3,3,5,5] are: - [3] with sum 3 - [3] with sum 3 - [5] with sum 5 - [5] with sum 5 - [3,3] with sum 6 - [3,5] with sum 8 - [5,5] with sum 10 - [3,3,5], with sum 11 - [3,5,5] with sum 13 - [3,3,5,5] with sum 16 Ordering the sums from smallest to largest gives 3, 3, 5, 5, 6, 8, 10, 11, 13, 16. The 7th smallest is 10.
Constraints:
n == nums.length
1 <= n <= 2 * 104
1 <= nums[i] <= 5 * 104
1 <= k <= n * (n + 1) / 2
Solutions
Solution 1: Binary Search + Two Pointers
We observe that all elements in the array are positive integers. The larger the subarray sum \(s\), the more subarrays there are with sums less than or equal to \(s\). This monotonicity allows us to use binary search to solve the problem.
We perform binary search on the subarray sum, initializing the left and right boundaries as the minimum value in the array \(\textit{nums}\) and the sum of all elements in the array, respectively. Each time, we calculate the number of subarrays with sums less than or equal to the current middle value. If the count is greater than or equal to \(k\), it means the current middle value \(s\) might be the \(k\)-th smallest subarray sum, so we shrink the right boundary. Otherwise, we increase the left boundary. After the binary search ends, the left boundary will be the \(k\)-th smallest subarray sum.
The problem reduces to calculating the number of subarrays in an array with sums less than or equal to \(s\), which we can compute using a function \(f(s)\).
The function \(f(s)\) is calculated as follows:
- Initialize two pointers \(j\) and \(i\), representing the left and right boundaries of the current window, with \(j = i = 0\). Also, initialize the sum of elements in the window \(t = 0\).
- Use a variable \(\textit{cnt}\) to record the number of subarrays with sums less than or equal to \(s\), initially \(\textit{cnt} = 0\).
- Traverse the array \(\textit{nums}\). For each element \(\textit{nums}[i]\), add it to the window, i.e., \(t = t + \textit{nums}[i]\). If \(t > s\), move the left boundary of the window to the right until \(t \leq s\), i.e., repeatedly execute \(t -= \textit{nums}[j]\) and \(j = j + 1\). Then update \(\textit{cnt}\) as \(\textit{cnt} = \textit{cnt} + i - j + 1\). Continue to the next element until the entire array is traversed.
Finally, return \(cnt\) as the result of the function \(f(s)\).
Time complexity is \(O(n \times \log S)\), where \(n\) is the length of the array \(\textit{nums}\), and \(S\) is the sum of all elements in the array \(\textit{nums}\). Space complexity is \(O(1)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|