老经典题了,不过如果不是这题我差点忘了单调队列的性质。。平时做的几乎都是单调栈
这题和区间的和相关,那么首先弄一个前缀和出来(记得偏移一位,在前面补上个0),然后再遍历这个前缀和数组
遍历过程中维护一个单调队列deque
维护单调性:第i个元素进队时弹出后面所有不小于它的
尺取更新答案:完成上面一步后,只要队尾-队首>=K,说明可以更新答案,然后将队首元素弹出
class Solution { public: int shortestSubarray(vector<int>& A, int K) { int n=A.size(); for(int i=0;i<n;i++)if(A[i]>=K)return 1; vector<int>pre(n+1); pre[0]=0;pre[1]=A[0]; for(int i=2;i<=n;i++) pre[i]=pre[i-1]+A[i-1]; deque<int>dq; dq.push_back(0); int ans=n+1; for(int i=1;i<=n;i++){ if(!dq.size()){dq.push_back(i);continue;} while(dq.size() && pre[dq.back()]>=pre[i])//元素入单调队列 dq.pop_back(); dq.push_back(i); //在单调队列上进行尺取 while(dq.size()>=2){ int dif=pre[dq.back()]-pre[dq.front()]; if(dif>=K){ ans=min(ans,dq.back()-dq.front()); dq.pop_front(); }else break; } } if(ans==n+1)ans=-1; return ans; } };