单调栈的完美应用场景. 结合单调栈和prefix sum. 这两个都是很好的解题方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public int shortestSubarray(int[] nums, int k) { long[] sumArray = new long[nums.length]; long sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; sumArray[i] = sum; } Deque<Integer> monoq = new LinkedList<>(); int ans = nums.length + 1; for (int i = 0; i < sumArray.length; i++) { while (!monoq.isEmpty() && sumArray[monoq.peekLast()] >= sumArray[i]) { monoq.pollLast(); } while (!monoq.isEmpty() && sumArray[i] - sumArray[monoq.peekFirst()] >= k) { ans = Math.min(ans, i - monoq.pollFirst()); } ans = sumArray[i] >= k ? Math.min(ans, i + 1) : ans; monoq.offer(i); } return ans == nums.length + 1 ? -1 : ans; } }
|
这道题经典啊. 单调queue的完美应用. 首先要注意的是我们prefix sum要用long数组存, 因为可能会overflow. 其次18行要注意, 因为可能某个位置的prefix sum不需要减前面的某个prefix sum, 只有这样才能凑成至少为k, 也就是15行的循环不会进去, 于是有了18行, 这一行就是为了捕捉这种情况.
时间复杂度: O(n) two pass
空间复杂度: O(n) 用了prefix sum array和deque.