Shortest Subarray with Sum at Least K
HARDDescription
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: 1
Example 2:
Input: nums = [1,2], k = 4 Output: -1
Example 3:
Input: nums = [2,-1,2], k = 3 Output: 3
Constraints:
1 <= nums.length <= 105-105 <= nums[i] <= 1051 <= k <= 109
Approaches
Checkout 2 different approaches to solve Shortest Subarray with Sum at Least K. Click on different approaches to view the approach and algorithm in detail.
Prefix Sum with Brute Force
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.
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 Analysis
Pros and Cons
- More efficient than a naive O(n^3) brute-force approach.
- Relatively easy to understand the logic based on prefix sums.
- 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.
Code Solutions
Checking out 4 solutions in different languages for Shortest Subarray with Sum at Least K. Click on different languages to view the code.
Video Solution
Watch the video walkthrough for Shortest Subarray with Sum at Least K
Similar Questions
5 related questions you might find useful
Algorithms:
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.