單調佇列 monotonic queue
阿新 • • 發佈:2021-11-10
239.Sliding Window Maximum
HardYou are given an array of integersnums
, there is a sliding window of sizek
which is moving from the very left of the array to the very right. You can only see thek
numbers in the window. Each time the sliding window moves right by one position.
Returnthe max sliding window
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] Explanation: Window position Max --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
Example 2:
Input: nums = [1], k = 1 Output: [1]
Example 3:
Input: nums = [1,-1], k = 1 Output: [1,-1]
Example 4:
Input: nums = [9,11], k = 2 Output: [11]
Example 5:
Input: nums = [4,-2], k = 2 Output: [4]
Constraints:
1 <= nums.length <= 105
-104<= nums[i] <= 104
1 <= k <= nums.length
class Solution { public int[] maxSlidingWindow(int[] nums, int k) { Deque<Integer> deque = new LinkedList(); int[] result = new int[nums.length-k+1]; for(int i=0;i<nums.length;i++){ //保持佇列單調遞減 while(!deque.isEmpty() && i-deque.peekFirst()>=k) deque.pollFirst(); //保持windowsize while(!deque.isEmpty() && nums[deque.peekLast()]<nums[i]) deque.pollLast(); deque.offerLast(i); int startInd = i-k+1; //佇列頭部值即為當前window的最大值 if(startInd>=0) result[startInd]=nums[deque.peekFirst()]; } return result; } }
時間複雜度:O(N)
862.Shortest Subarray with Sum at Least K
HardGiven an integer arraynums
and an integerk
, returnthe length of the shortest non-emptysubarrayofnums
with a sum of at leastk
. If there is no suchsubarray, return-1
.
Asubarrayis acontiguouspart of an array.
Example 1:
Input: nums = [1], k = 1 Output: 1
Example 2:
Input: nums = [1,2], k = 4 Output: -1
Example 3:
Input: nums = [2,-1,2], k = 3 Output: 3
Constraints:
1 <= nums.length <= 105
-105<= nums[i] <= 105
1 <= k <= 109
class Solution { public int shortestSubarray(int[] nums, int k) { int len = nums.length; if(len==1) return nums[0]>=k ? 1 : -1; long[] sum = new long[len+1]; sum[0]=0; //先計算字首和 for(int i=1;i<=len;i++) sum[i]=sum[i-1]+nums[i-1]; Deque<Integer> dq = new LinkedList(); int result = len+1; for(int i=0;i<=len;i++){ //保持佇列單調遞增 while(!dq.isEmpty() && sum[dq.peekLast()]>=sum[i]) dq.pollLast(); //與佇列頭部元素比較,如果滿足條件,pop並記錄結果。 為啥滿足條件時可以直接pop? 因為即使i之後還有元素滿足條件,也已經不是最小長度了 while(!dq.isEmpty() && sum[dq.peekFirst()]+k<=sum[i]) { result = Math.min(result,i-dq.pollFirst()); } dq.offerLast(i); } return result>len ? -1 : result; } }
時間複雜度:O(N)