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.
For example:
nums = [1], k = 1
Output: 1nums = [1, 2], k = 4
Output: -1nums = [2, -1, 2], k = 3
Output: 3Constraints:
1 <= nums.length <= 10^5
-10^5 <= nums[i] <= 10^5
1 <= k <= 10^9
Explain your approach and provide code.
The most straightforward approach is to check all possible subarrays and find the shortest one with a sum of at least k
. This involves two nested loops to define the start and end indices of the subarray, and an inner loop (or a sum calculation within the outer loops) to compute the sum of the subarray. This is not the optimal solution, but it's good to start with to understand the problem.
Algorithm:
i
from 0 to n-1
.i
, iterate through all possible end indices j
from i
to n-1
.nums[i...j]
.k
, update the minimum length if the current subarray's length is smaller.k
is found, return -1.Code Example (Python):
def shortest_subarray_brute_force(nums, k):
n = len(nums)
min_length = float('inf')
for i in range(n):
for j in range(i, n):
subarray_sum = sum(nums[i:j+1])
if subarray_sum >= k:
min_length = min(min_length, j - i + 1)
if min_length == float('inf'):
return -1
else:
return min_length
Time Complexity: O(n^3), where n is the length of the input array. The nested loops take O(n^2) time, and the sum calculation inside the loops takes O(n) time in the worst case.
Space Complexity: O(1). We only use a few variables to store the minimum length and the subarray sum.
A more efficient approach uses a sliding window technique combined with a monotonic queue (deque). The idea is to maintain a queue of prefix sums, where the queue is monotonically increasing. This allows us to efficiently find the shortest subarray with a sum of at least k
.
Algorithm:
nums
. Let prefix_sum[i]
be the sum of nums[0...i-1]
. prefix_sum[0]
is 0.k
, update the minimum length and remove the front element from the deque. This step shrinks the window from the left.k
is found, return -1.Code Example (Python):
from collections import deque
def shortest_subarray(nums, k):
n = len(nums)
prefix_sum = [0] * (n + 1)
for i in range(n):
prefix_sum[i + 1] = prefix_sum[i] + nums[i]
min_length = float('inf')
deque_indices = deque()
for i in range(n + 1):
while deque_indices and prefix_sum[i] - prefix_sum[deque_indices[0]] >= k:
min_length = min(min_length, i - deque_indices.popleft())
while deque_indices and prefix_sum[i] <= prefix_sum[deque_indices[-1]]:
deque_indices.pop()
deque_indices.append(i)
if min_length == float('inf'):
return -1
else:
return min_length
Time Complexity: O(n), where n is the length of the input array. Each element is added and removed from the deque at most once.
Space Complexity: O(n), where n is the length of the input array. The prefix sum array and the deque can store at most n elements.
Edge Cases: