Kth Smallest Subarray Sum
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given an integer array nums of length n and an integer k, return thekth 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.
Examples
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.length1 <= n <= 2 * 10^41 <= nums[i] <= 5 * 10^41 <= k <= n * (n + 1) / 2
Solution
Method 1 – Binary Search with Sliding Window
Intuition
The k-th smallest subarray sum can be found by binary searching the possible sum values and, for each candidate sum, counting how many subarrays have sum ≤ that value. The counting can be done efficiently using a sliding window since all elements are positive.
Approach
- Set left = min(nums), right = sum(nums).
- While left < right:
- Compute mid = (left + right) // 2.
- Count the number of subarrays with sum ≤ mid using a sliding window.
- If the count ≥ k, set right = mid; else, set left = mid + 1.
- Return left as the answer.
Code
C++
class Solution {
public:
int kthSmallestSubarraySum(vector<int>& nums, int k) {
int l = *min_element(nums.begin(), nums.end()), r = accumulate(nums.begin(), nums.end(), 0);
while (l < r) {
int m = (l + r) / 2, cnt = 0, sum = 0, j = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
while (sum > m) sum -= nums[j++];
cnt += i - j + 1;
}
if (cnt >= k) r = m;
else l = m + 1;
}
return l;
}
};
Go
func kthSmallestSubarraySum(nums []int, k int) int {
l, r := nums[0], 0
for _, v := range nums {
if v < l { l = v }
r += v
}
for l < r {
m := (l + r) / 2
cnt, sum, j := 0, 0, 0
for i := 0; i < len(nums); i++ {
sum += nums[i]
for sum > m {
sum -= nums[j]
j++
}
cnt += i - j + 1
}
if cnt >= k {
r = m
} else {
l = m + 1
}
}
return l
}
Java
class Solution {
public int kthSmallestSubarraySum(int[] nums, int k) {
int l = Arrays.stream(nums).min().getAsInt(), r = Arrays.stream(nums).sum();
while (l < r) {
int m = (l + r) / 2, cnt = 0, sum = 0, j = 0;
for (int i = 0; i < nums.length; ++i) {
sum += nums[i];
while (sum > m) sum -= nums[j++];
cnt += i - j + 1;
}
if (cnt >= k) r = m;
else l = m + 1;
}
return l;
}
}
Kotlin
class Solution {
fun kthSmallestSubarraySum(nums: IntArray, k: Int): Int {
var l = nums.minOrNull()!!
var r = nums.sum()
while (l < r) {
val m = (l + r) / 2
var cnt = 0
var sum = 0
var j = 0
for (i in nums.indices) {
sum += nums[i]
while (sum > m) {
sum -= nums[j]
j++
}
cnt += i - j + 1
}
if (cnt >= k) r = m else l = m + 1
}
return l
}
}
Python
class Solution:
def kthSmallestSubarraySum(self, nums: list[int], k: int) -> int:
l, r = min(nums), sum(nums)
while l < r:
m = (l + r) // 2
cnt = 0
s = j = 0
for i, v in enumerate(nums):
s += v
while s > m:
s -= nums[j]
j += 1
cnt += i - j + 1
if cnt >= k:
r = m
else:
l = m + 1
return l
Rust
impl Solution {
pub fn kth_smallest_subarray_sum(nums: Vec<i32>, k: i32) -> i32 {
let (mut l, mut r) = (*nums.iter().min().unwrap(), nums.iter().sum());
while l < r {
let m = (l + r) / 2;
let (mut cnt, mut sum, mut j) = (0, 0, 0);
for i in 0..nums.len() {
sum += nums[i];
while sum > m { sum -= nums[j]; j += 1; }
cnt += i as i32 - j as i32 + 1;
}
if cnt >= k { r = m; } else { l = m + 1; }
}
l
}
}
TypeScript
class Solution {
kthSmallestSubarraySum(nums: number[], k: number): number {
let l = Math.min(...nums), r = nums.reduce((a, b) => a + b, 0);
while (l < r) {
const m = Math.floor((l + r) / 2);
let cnt = 0, sum = 0, j = 0;
for (let i = 0; i < nums.length; ++i) {
sum += nums[i];
while (sum > m) sum -= nums[j++];
cnt += i - j + 1;
}
if (cnt >= k) r = m;
else l = m + 1;
}
return l;
}
}
Complexity
- ⏰ Time complexity:
O(n log S), where n is the length of nums and S is the sum of nums. Each binary search step counts subarrays in O(n). - 🧺 Space complexity:
O(1), only a few variables are used.