[Hard] 862. Shortest Subarray with Sum at Least K
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.
Examples
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 <= 10^5-10^5 <= nums[i] <= 10^51 <= k <= 10^9
Thinking Process
- Negative Numbers Break Simple Sliding Window: Cannot shrink window from left when sum >= k
- If
preSum[i] <= preSum[j]andi < j, theniis always better - Remove from front: processed starting positions
- Remove from back: maintain monotonic property
- If
- Maintain a window
[left, right]satisfying a constraint. - Expand
rightto grow; shrinkleftwhen invalid. - Fixed window: slide both pointers together.
Common Approaches
Typical techniques for this pattern:
| Approach | Time | Space | Notes |
|---|---|---|---|
| Fixed-size window (this problem) | O(n) | O(1) | Window size known upfront |
| Variable-size window | O(n) | O(1) | Expand/shrink until valid |
| Window + hash map | O(n) | O(k) | Track character/count frequencies |
| Deque window max | O(n) | O(k) | Monotonic deque for max/min in window |
Solution
class Solution {
public:
int shortestSubarray(vector<int>& nums, int k) {
if(nums.empty()) return -1;
const int N = nums.size();
vector<long> preSum(N + 1);
for(int i = 0; i < N; i++) {
preSum[i + 1] = preSum[i] + nums[i];
}
int rtn = INT_MAX;
deque<int> q;
for(int i = 0; i <= N; i++) {
long curSum = preSum[i];
while(!q.empty() && curSum - preSum[q.front()] >= k) {
rtn = min(rtn, i - q.front());
q.pop_front();
}
while(!q.empty() && preSum[q.back()] >= curSum) {
q.pop_back();
}
q.push_back(i);
}
return rtn == INT_MAX? -1: rtn;
}
};
Solution Explanation
Approach: Fixed-size window (this problem)
Key idea: 1. Negative Numbers Break Simple Sliding Window: Cannot shrink window from left when sum >= k
How the code works:
- Negative Numbers Break Simple Sliding Window: Cannot shrink window from left when sum >= k
- If
preSum[i] <= preSum[j]andi < j, theniis always better - Remove from front: processed starting positions
- Remove from back: maintain monotonic property
- Maintain a window
[left, right]satisfying a constraint. - Expand
rightto grow; shrinkleftwhen invalid.
- If
Walkthrough — input nums = [1], k = 1, expected output 1:
- Initialize variables from the problem setup.
- Apply the main loop / recursion until the condition is met.
- Confirm the result matches the expected output.
Common Mistakes
- Empty array:
nums = []→ return-1 - No valid subarray:
nums = [1,2],k = 4→ return-1 - Single element:
nums = [1],k = 1→ return1 - Negative numbers:
nums = [2,-1,2],k = 3→ return3 - All negative:
nums = [-1,-2,-3],k = 1→ return-1 -
Large k:
nums = [1,2],k = 10^9→ return-1 - Using simple sliding window: Fails with negative numbers
- Not maintaining monotonic property: Leads to incorrect results
- Wrong deque operations: Removing from wrong end
- Integer overflow: Not using
longfor prefix sums - Index confusion: Mixing 0-indexed and 1-indexed arrays
- Not checking empty deque: Accessing
q.front()orq.back()without checking
Comparison with LC 209
| Aspect | LC 209 (All Positive) | LC 862 (Can Have Negatives) |
|---|---|---|
| Approach | Simple sliding window | Monotonic deque |
| Time | O(n) | O(n) |
| Space | O(1) | O(n) |
| Complexity | Simpler | More complex |
| Key Insight | Shrink window when sum >= k | Maintain monotonic deque |
Related Problems
- LC 209: Minimum Size Subarray Sum - Similar but all positive numbers
- LC 3: Longest Substring Without Repeating Characters - Sliding window pattern
- LC 76: Minimum Window Substring - Similar sliding window
- LC 53: Maximum Subarray - Maximum sum subarray
- LC 239: Sliding Window Maximum - Monotonic deque pattern
Key Takeaways
-
Negative Numbers Break Simple Sliding Window: Cannot shrink window from left when sum >= k
-
Prefix Sum Enables Range Queries:
preSum[j+1] - preSum[i]= sum fromitoj - Monotonic Deque: Maintains indices with increasing prefix sums
- If
preSum[i] <= preSum[j]andi < j, theniis always better
- If
- Why Deque?: Need O(1) operations on both ends
- Remove from front: processed starting positions
- Remove from back: maintain monotonic property
- Two While Loops:
- First loop: find valid subarrays ending at current position
- Second loop: maintain monotonic property for future positions
References
- LC 862: Shortest Subarray with Sum at Least K on LeetCode
- LeetCode Discuss — LC 862: Shortest Subarray with Sum at Least K
- LeetCode Editorial (may require premium)