Given an integer array nums of length n and an integer k, return the kthsmallest 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
public int kthSmallestSubarraySum(int[] nums, int k) {
if (nums == null || nums.length == 0 || k < 1) {
return 0;
}
int total = 0;
int min = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
total = total + nums[i];
min = Math.min(min, nums[i]);
}
int start = min;
int end = total;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (countSumLessOrEqualToTarget(nums, mid) > k) {
end = mid;
} else if (countSumLessOrEqualToTarget(nums, mid) < k) {
start = mid;
} else {
end = mid;
}
}
if (countSumLessOrEqualToTarget(nums, start) >= k) {
return start;
}
if (countSumLessOrEqualToTarget(nums, end) >= k) {
return end;
}
return 0;
}
private int countSumLessOrEqualToTarget(int[] nums, int target) {
int sum = 0;
int count = 0;
int left = 0;
for (int right = 0; right < nums.length; right++) {
sum = sum + nums[right];
while (sum > target) {
sum = sum - nums[left];
left++;
}
count = count + right - left + 1;
}
return count;
}