作者:
晚于: 2020-07-15 12:00:00后提交分数乘系数50%
截止日期: 2020-07-22 12:00:00
问题描述 :
返回 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
可参考以下main函数:
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;
}
输入说明 :
首先输入A数组元素的数目n
然后输入n个整数
最后输入k
输出说明 :
输出一个整数,表示结果
输入范例 :
3 2 -1 2 3
输出范例;
3
#include <iostream> #include <vector> #include <queue> using namespace std; //使用单调的双端队列 从队头到队尾是递增的 //首先计算前缀和sum[i+1] //我们要找的是sum[x2]-sum[x1]>=k 且 x2-x1最小 //每次入队时 先比较队尾元素是否比自己大 如果比自己大就将队尾元素pop //然后从队头开始比较与自己比较 若差大于等于k则符合要求 res=min(res,自己的坐标减去队头元素的坐标) 将当前队头pop class Solution { public: int shortestSubarray(vector<int>& A, int K) { vector<int> presum(A.size()+1,0); int i,len=A.size()+1; deque<int> Q;//存储下标,按照队内presum升序 Q.push_back(0); //边界条件,前缀和为0,下标为0 for(i=0;i<A.size();i++) { presum[i+1]=presum[i]+A[i]; while(!Q.empty()&&presum[Q.back()]>presum[i+1]) Q.pop_back(); while(!Q.empty()&&(presum[i+1]-presum[Q.front()]>=K)) { len=min(len,i+1-Q.front()); Q.pop_front(); } Q.push_back(i); } if(len==A.size()+1) return -1; else return len; } private: int min(int a,int b) { if(a>b) return b; else return a; } }; 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; } //https://blog.csdn.net/qq_21201267/article/details/105662545?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight