1. 程式人生 > 其它 >單調佇列 monotonic queue

單調佇列 monotonic queue

239.Sliding Window Maximum

Hard

You are given an array of integersnums, there is a sliding window of sizekwhich is moving from the very left of the array to the very right. You can only see theknumbers 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

Hard

Given an integer arraynumsand an integerk, returnthe length of the shortest non-emptysubarrayofnumswith 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)