题目所属分类
重点:滑动窗口加优先队列这道题
(面试常考)
前缀和如果单调 就可以考虑双指针算法 但是这道题的前缀和并不单调,
原题链接
给你一个整数数组 nums 和一个整数 k ,找出 nums 中和至少为 k 的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回 -1 。
子数组 是数组中 连续 的一部分。
代码案例:输入:nums = [1], k = 1
输出:1
提示:
1 <= nums.length <= 105
-105 <= nums[i] <= 105
1 <= k <= 109
题解
典型的单调队列是找滑动窗口的极值 但是这道题的非典型的单调队列
class Solution {
public int shortestSubarray(int[] nums, int k) {
int n = nums.length ;
long[] s = new long[n+1];
for(int i = 1 ; i <= n ; i++) s[i] = s[i-1] + nums[i-1];
Deque<Integer> q = new LinkedList<>();
q.add(0);
int res = Integer.MAX_VALUE;
for(int i = 1 ; i <= n ;i++){
while(!q.isEmpty()&& s[q.peekFirst()] + k <= s[i]){
res = Math.min(res , i - q.peekFirst() );
q.pollFirst();
}
//将所有大于等于s[i]的数删掉
while (!q.isEmpty() && s[q.peekLast()] >= s[i]) q.pollLast();
q.add(i);
}
if(res == Integer.MAX_VALUE) return -1 ;
return res ;
}
}