[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
from collections import deque
class Solution:
def shortestSubarray(self, nums, k):
if not nums:
return -1
N = len(nums)
preSum = [0] * (N + 1)
for i in range(N):
preSum[i + 1] = preSum[i] + nums[i]
rtn = float('inf')
q = deque()
for i in range(N + 1):
curSum = preSum[i]
while q and curSum - preSum[q[0]] >= k:
rtn = min(rtn, i - q.popleft())
while q and preSum[q[-1]] >= curSum:
q.pop()
q.append(i)
return -1 if rtn == float('inf') else 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)