问题:
力扣的第209道题209. 长度最小的子数组 - 力扣(LeetCode)很简单的滑动窗口,但是如果数组中有负数,那就有点麻烦了,例如力扣的第86道题862. 和至少为 K 的最短子数组 - 力扣(LeetCode)
解题思路:
前缀和加双端队列(保持单调递增)
遍历前缀
如果队尾的元素大于等于前缀i,表明,此时新添的元素是个负数,对于后续找找满足的条件可以去除更多的个数,所以维护队列的单调
如果当前前缀i-队列的首位>=k,记录此时的长度,然后poll首列,因为后续满足的条件都没有当前短
代码:
class Solution { public int shortestSubarray(int[] nums, int k) { int size = nums.length; long[] pre = new long[size + 1]; int res = size + 1; for(int i = 1; i <= size; i++){ pre[i] = pre[i - 1] + nums[i - 1]; if(nums[i - 1] == k){ return 1; } } Deque<Integer> dq = new LinkedList<>(); for(int i = 0; i <= size; i++){ while(!dq.isEmpty() && pre[i] <= pre[dq.getLast()]){ dq.removeLast(); } while(!dq.isEmpty() && pre[i] - pre[dq.peek()]>=k){ res = Math.min(res,i - dq.poll()); } dq.add(i); } return res == size + 1? -1 : res; } }
版权声明:本文为xinjiao22222原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。