Shortest Subarray with Sum at Least K
HardPrompt
Given an integer array nums and an integer k, return the length of the shortest non-empty subarray of nums with a sum of at least k. If there is no such subarray, return -1.
A subarray is a contiguous part of an array.
Example 1:
Input: nums = [1], k = 1
Output: 1Example 2:
Input: nums = [1,2], k = 4
Output: -1Example 3:
Input: nums = [2,-1,2], k = 3
Output: 3
Constraints:
1 <= nums.length <= 105-105 <= nums[i] <= 1051 <= k <= 109
Approaches
2 approaches with complexity analysis and trade-offs.
A straightforward but inefficient approach involves pre-calculating prefix sums to quickly find the sum of any subarray. We then iterate through all possible start and end points of a subarray, check if its sum is at least k, and keep track of the minimum length found.
Algorithm
- Create a prefix sum array
prefixof sizen + 1. Uselongto prevent integer overflow, as sums can be large. - Populate the
prefixarray:prefix[i+1] = prefix[i] + nums[i]forifrom0ton-1. - Initialize
minLength = n + 1to store the result. - Iterate with a start index
ifrom0ton-1. - Inside this loop, iterate with an end index
jfromiton-1. - Calculate the subarray sum:
sum = prefix[j+1] - prefix[i]. - If
sum >= k, updateminLength = Math.min(minLength, j - i + 1). - After the loops, if
minLengthis stilln + 1, return-1. Otherwise, returnminLength.
Walkthrough
This method improves upon a naive brute-force solution by optimizing the sum calculation for each subarray.
-
Prefix Sum Calculation: First, we create a prefix sum array,
prefix, of sizen + 1, wherenis the length ofnums.prefix[i]stores the sum of elements fromnums[0]tonums[i-1].prefix[0]is initialized to 0. This allows us to calculate the sum of any subarraynums[i...j]in constant time using the formulaprefix[j+1] - prefix[i]. This pre-computation step takes O(n) time. -
Iterating Subarrays: After computing the prefix sums, we use two nested loops to examine every possible non-empty subarray. The outer loop selects a starting index
ifrom0ton-1, and the inner loop selects an ending indexjfromiton-1. -
Checking Condition: For each subarray defined by
(i, j), we calculate its sumprefix[j+1] - prefix[i]. If this sum is greater than or equal tok, we have found a valid subarray. We then update our minimum length found so far withmin(minLength, j - i + 1). -
Result: We initialize
minLengthto a value larger thann(e.g.,n + 1). IfminLengthremains this value after checking all subarrays, it means no solution exists, and we return -1. Otherwise, we return the finalminLength.
class Solution { public int shortestSubarray(int[] nums, int k) { int n = nums.length; long[] prefix = new long[n + 1]; for (int i = 0; i < n; i++) { prefix[i + 1] = prefix[i] + nums[i]; } int minLength = n + 1; for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { long sum = prefix[j + 1] - prefix[i]; if (sum >= k) { minLength = Math.min(minLength, j - i + 1); } } } return minLength == n + 1 ? -1 : minLength; }}Complexity
Time
O(n^2), where n is the number of elements in `nums`. The prefix sum calculation takes O(n), but the nested loops to check every subarray dominate the runtime.
Space
O(n) to store the prefix sum array.
Trade-offs
Pros
More efficient than a naive O(n^3) brute-force approach.
Relatively easy to understand the logic based on prefix sums.
Cons
The O(n^2) time complexity is too slow for the given constraints (n <= 10^5) and will result in a 'Time Limit Exceeded' error.
Solutions
Solution
class Solution {public int shortestSubarray(int[] nums, int k) { int n = nums.length; long[] s = new long[n + 1]; for (int i = 0; i < n; ++i) { s[i + 1] = s[i] + nums[i]; } Deque<Integer> q = new ArrayDeque<>(); int ans = n + 1; for (int i = 0; i <= n; ++i) { while (!q.isEmpty() && s[i] - s[q.peek()] >= k) { ans = Math.min(ans, i - q.poll()); } while (!q.isEmpty() && s[q.peekLast()] >= s[i]) { q.pollLast(); } q.offer(i); } return ans > n ? -1 : ans; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.