问题描述 :
返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。
如果没有和至少为 K 的非空子数组,返回 -1 。
示例 1:
输入:A = [1], K = 1
输出:1
示例 2:
输入:A = [1,2], K = 4
输出:-1
示例 3:
输入:A = [2,-1,2], K = 3
输出:3
说明:
1 <= A.length <= 50000
-10 ^ 5 <= A[i] <= 10 ^ 5
1 <= K <= 10 ^ 9
输入说明 :
首先输入A数组元素的数目n
然后输入n个整数
最后输入k
输出说明 :
输出一个整数,表示结果
输入范例 :
3
2 -1 2
3
输出范例 :
3
/*
构造前缀和数组,用双端队列来对前缀和数组升序排队
排队的思想是:当排到自己时,先要将队伍中最后一个比自己高的人踢出,直到前面所有人比自己矮
之后就从队伍的第一个同学开始比较,得到使得和至少为k的最短数组
*/
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
class Solution {
public:
int shortestSubarray(vector<int>& A, int K) {
int n = A.size();
vector<int> sum(n+1,0); //前缀和数组
for(int i = 0; i < n; i++) {
sum[i+1] = sum[i] + A[i];
}
deque<int> dq;
int j = 0;
int res = n+1;
while(j <= n) {
while(!dq.empty() && sum[j] <= sum[dq.back()]) {
dq.pop_back(); //去掉比自己高的人
}
while(!dq.empty() && sum[j]-sum[dq.front()] >= K) {
res = min(res,j-dq.front()); //从第一个人开始比较
dq.pop_front();
}
dq.push_back(j); //加入队伍
j++;
}
return res == n+1 ? -1 : res;
}
};
int main()
{
vector<int> A;
int n,data,k;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data;
A.push_back(data);
}
cin>>k;
int result=Solution().shortestSubarray(A,k);
cout<<result<<endl;
return 0;
}