Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K.
If there is no non-empty subarray with sum at least K, return -1.
Example 1:
Input: A = [1], K = 1 Output: 1
Example 2:
Input: A = [1, 2], K = 4 Output: -1
Example 3:
Input: A = [2, 1, 2], K = 3 Output: 3
思路:
最开始我的思路用一把越来越大的尺子,每次从左往右移,只要有尺子在一个位置上的和大于等于K,那就直接返回当前尺子的长度,而且在计算尺子内的值的和时,可以先算出第一个位置上的和,之后往后移动的时候,每次加上新的值(right),减去旧的值(left - 1)。这样只要答案的长度不是太大,大循环(每次尺子长度+1)就不会循环太多次。
int shortestSubarray(vector<int>& A, int K)
{
if(A.size() == 1)
return A[0] >= K ? 1 : 0;
bool isFind;
for(int i = 0; i < A.size(); i++) // 先看看每个数有没有
{
if(A[i] >= K)
return 1;
}
for(int len = 1; len < A.size(); len++) // 每次循环用len长度的尺子从左往右走
{
int left = 0;
int right = len;
int cur_sum = 0;
for(int t = left; t <= right; t++)
cur_sum += A[t];
if(cur_sum >= K)
return len + 1;
while(right < A.size() - 1)
{
++left;
++right;
cur_sum += A[right];
cur_sum -= A[left - 1];
if(cur_sum >= K)
return len + 1;
}
}
return -1;
}
思路以及答案没有问题,但是25万个数的时候,超时了,答案使用deque(有的使用priority_queue)来完成。大致思路是,计算每个位置上,加上后边多少位的数,能够大于等于K,找出最小的。
int shortestSubarray(vector<int> A, int K)
{
int N = A.size(), res = N + 1;
vector<int> B(N + 1, 0);
for (int i = 0; i < N; i++) B[i + 1] += B[i] + A[i];
deque<int> d;
for (int i = 0; i < N + 1; i++)
{
while (d.size() > 0 && B[i] - B[d.front()] >= K)
res = min(res, i - d.front()), d.pop_front();
while (d.size() > 0 && B[i] <= B[d.back()]) d.pop_back();
d.push_back(i);
}
return res <= N ? res : -1;
}