返回 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
Java
class Solution { public int shortestSubarray(int[] A, int K) { int n=A.length; int res=n+1; int[] B=new int[n+1]; for(int i=0;i<n;i++)B[i+1]=B[i]+A[i];//Calculate prefix sum B of list A. //B[j] - B[i] represents the sum of subarray A[i] ~ A[j-1] Deque<Integer> d=new ArrayDeque<>();//Deque d will keep indexes of increasing B[i]. for(int i=0;i<n+1;i++){ //for B[i], find the smallest j that B[j] - B[i] >= K. //we start to compare B[i] with the smallest prefix sum in our deque, which is B[D[0]], hoping that B[i] - B[d[0]] >= K. while(!d.isEmpty()&&B[i]-B[d.getFirst()]>=K) res=Math.min(res,i-d.pollFirst());//if B[i] - B[d[0]] >= K, we can update our result res = min(res, i - d.popleft()). //D[0] exists in our deque, it means that before B[i], we didn't find a subarray whose sum at least K. //B[i] is the first prefix sum that valid this condition. //In other words, A[D[0]] ~ A[i-1] is the shortest subarray starting at A[D[0]] with sum at least K. //We have already find it for A[D[0]] and it can't be shorter, so we can drop it from our deque. while(!d.isEmpty()&&B[i]<=B[d.getLast()])//keep B[D[i]] increasing in the deque. //compared with d.back(),B[i] can help us make the subarray length shorter and sum bigger d.pollLast();//So no need to keep d.back() in our deque. d.addLast(i); } return res<=n? res:-1; } }
cpp
class Solution { public: int shortestSubarray(vector<int>& A, int K) { int N = A.size(), res = N + 1; deque<int> d; for (int i = 0; i < N; i++) { if (i > 0) A[i] += A[i - 1]; if (A[i] >= K) res = min(res, i + 1); while (!d.empty() && A[i] - A[d.front()] >= K) res = min(res, i - d.front()), d.pop_front(); while (!d.empty() && A[i] <= A[d.back()]) d.pop_back(); d.push_back(i); } return res <= N ? res : -1; } };
py
class Solution: def shortestSubarray(self, A: List[int], K: int) -> int: d=collections.deque([[0,0]]) res=float('inf') cur=0 for i,a in enumerate(A): cur+=a while d and cur-d[0][1]>=K: res=min(res,i+1-d.popleft()[0]) while d and cur<=d[-1][1]: d.pop() d.append([i+1,cur]) return -1 if res==float('inf') else res