给你一个整数数组 nums
和一个整数 k
,找出 nums
中和至少为 k
的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回 -1
。
子数组 是数组中 连续 的一部分。
示例 1:
输入:nums = [1], k = 1 输出:1
示例 2:
输入:nums = [1,2], k = 4 输出:-1
示例 3:
输入:nums = [2,-1,2], k = 3 输出:3
提示:
1 <= nums.length <= 105
-105 <= nums[i] <= 105
1 <= k <= 109
class Solution {
public int shortestSubarray(int[] nums, int k) {
int result = Integer.MAX_VALUE, n = nums.length, head = 0, tail = head;
long[] preSum = new long[n + 1];
/** 步骤1:构建前缀和 */
for (int i = 0; i < n; i++) {
if (nums[i] >= k) return 1;
preSum[i + 1] = preSum[i] + nums[i];
}
/** 步骤2:构建单调栈和使用单调栈求最小值 */
int[] queue = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
while (head != tail && preSum[queue[tail - 1]] >= preSum[i])
tail--;
queue[tail++] = i;
while (head != tail && preSum[i] - preSum[queue[head]] >= k)
result = Math.min(i - queue[head++], result);
}
return result == Integer.MAX_VALUE ? -1 : result;
}
}