我正在研究问题Shortest Subarray with Sum at Least K,其中最佳解决方案使用双端队列。
由于数组可以同时具有正值和负值,因此无法使用双指针技术。我了解为什么2指针技术无法正常工作。
我对使用双端队列的最佳解决方案的理解如下:
prefix = [a, b, c]
和prefix[b] < prefix[a]
则(c-b) > (c-a)
,并且由于[b,c]
小于[a,b,c]
,双端队列单调递增。总和至少为k的最短子数组的代码如下:
public int shortestSubarray(int[] a, int k) {
Deque<Integer> deque = new LinkedList<>();
int res = a.length+1;
int[] prefix = new int[a.length+1];
for(int i = 1; i<prefix.length; i++)
prefix[i] = prefix[i-1] + a[i-1];
for(int i = 0; i<prefix.length; i++) {
// increment start pointer when condition is violated
// this first while loop is same as what happens in the 2 pointer approach
while(!deque.isEmpty() && prefix[i] - prefix[deque.peekLast()] >= k) {
res = Math.min(res, i - deque.peekLast());
deque.removeLast();
}
// this is what changes the solution from 2 pointer
// we filter out candidates that cannot be the start for min subarray
while(!deque.isEmpty() && prefix[i] <= prefix[deque.peekFirst()]) {
deque.removeFirst();
}
deque.addFirst(i);
}
return res == a.length+1? -1 : res;
}
我想我理解为什么这种特殊的解决方案有效,但是我仍然困惑何时可以使用双端队列来优化滑动窗口问题。
我的问题
我开始考虑如果问题是找到总和为最小K的最长子阵列而不是最短子阵列,
谢谢。