#862 Shortest Subarray with Sum at Least K
frequently reported atGoldman SachsAmazonGoogle
the problem
In plain words
Return the length of the shortest non-empty subarray of nums whose sum is at least k, or −1 if none exists. nums may contain negative numbers.
in nums = [1], k = 1
out 1
in nums = [1,2], k = 4
out -1
in nums = [2,-1,2], k = 3
out 3
- 1 ≤ n ≤ 10⁵
- -10⁵ ≤ nums[i] ≤ 10⁵
- 1 ≤ k ≤ 10⁹
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternMonotonic dequePrefix sums
With prefix sums P, a subarray (i, j] works when P[j] − P[i] ≥ k. Keep candidate starts i in a deque with increasing P. A start with a larger P than a later one is useless; a start that already succeeded can retire, because later ends are only longer.
solutions
From brute force to optimal
For each start, add elements until the sum ≥ k; record the length.
- For each i: running sum over j = i, i+1, …
- On the first sum ≥ k, record j − i + 1 and stop that start.
n starts, each may scan to the end.
A running sum (as long).
class Solution { public int shortestSubarray(int[] nums, int k) { int n = nums.length; int best = Integer.MAX_VALUE; for (int i = 0; i < n; i++) { long sum = 0; for (int j = i; j < n; j++) { sum += nums[j]; if (sum >= k) { best = Math.min(best, j - i + 1); break; // longer subarrays from the same start can't be shorter } } } return best == Integer.MAX_VALUE ? -1 : best; }}For each end j: pop good starts from the front (recording lengths), pop worse starts from the back, then add j.
- Build
longprefix sums P[0..n]. - For j = 0..n: while P[j] − P[front] ≥ k, record j − front and poll the front.
- While P[back] ≥ P[j], poll the back (j is a later, lower start — strictly better).
- Offer j.
Each prefix index enters and leaves the deque at most once.
The prefix array and the deque.
class Solution { public int shortestSubarray(int[] nums, int k) { int n = nums.length; long[] prefix = new long[n + 1]; // sum(nums[i..j-1]) = prefix[j] - prefix[i] for (int i = 0; i < n; i++) prefix[i + 1] = prefix[i] + nums[i]; int best = n + 1; Deque<Integer> dq = new ArrayDeque<>(); // start candidates, prefix values increasing for (int j = 0; j <= n; j++) { while (!dq.isEmpty() && prefix[j] - prefix[dq.peekFirst()] >= k) { best = Math.min(best, j - dq.pollFirst()); // later ends would only be longer: retire it } while (!dq.isEmpty() && prefix[dq.peekLast()] >= prefix[j]) { dq.pollLast(); // j starts later with a smaller-or-equal prefix: always better } dq.offerLast(j); } return best <= n ? best : -1; }}in the room
How to say it in the interview
talk track
- Say why the sliding window from the Sliding Window chapter fails: with negatives, shrinking the window can increase the sum.
- Explain both pop rules separately — front pops are about answers, back pops are about dominance.
traps
- Using
intprefix sums — 10⁵ × 10⁵ = 10¹⁰ overflows. - Using a two-pointer window, which is only correct for non-negative numbers (LC 209).
what they ask next
Follow-ups
All numbers non-negative?
Then a plain sliding window works in O(n) with O(1) space — that's LC 209 Minimum Size Subarray Sum.
before you submit
Edge cases to test
- No subarray reaches k (for example, all negative numbers) → −1.
- One element ≥ k on its own → 1.
- Prefix sums can pass 2³¹ − 1 (10⁵ values of 10⁵), so store them as
long. - Negatives break the two-pointer window: shrinking it can raise the sum.
practise next
Similar problems
- #239Sliding Window MaximumHardin Queues
- #209Minimum Size Subarray SumMediumin Sliding Window
- #560Subarray Sum Equals KMediumin Hashing