1. 程式人生 > >239. Sliding Window Maximum

239. Sliding Window Maximum

integer 元素 etc public info 每次 n) 雙端 入隊

一、題目

  1、審題

  技術分享圖片

  2、分析

    給出一個整形數組,一個窗口大小 k,此窗口每次包含 k 個連續元素,依次向後移動,將每次窗口中的最大元素進行記錄。

二、解答

  1、思路

    方法一、

      采用雙端隊列 Deque 存儲每次窗口中最大元素的下標 i,且隊列中存儲的下標是依次增大的。

      ①、循環判斷隊列中元素值 < i - k + 1,則元素出隊列。

      ②、循環判斷,隊列後部分的元素下標對應的元素值是否小於當前遍歷的元素的值,若是,則從後部依次出隊。 // 保證了下標對應的元素的值是遞增的。

      ③、當前元素下標入隊。

      解釋不是太清楚,具體摘自:

        https://leetcode.com/problems/sliding-window-maximum/discuss/65881/O(n)-solution-in-Java-with-two-simple-pass-in-the-array

    public int[] maxSlidingWindow2(int[] nums, int k) {
        
        if(nums == null || k <= 0)
            return new int[0];
        
        int n = nums.length;
        
int[] r = new int[n - k + 1]; int ri = 0; Deque<Integer> q = new ArrayDeque<>(); // store index for(int i = 0; i < n; i++) { // remove numbers out of range k while(!q.isEmpty() && q.peek() < i - k + 1) q.poll();
// remove smaller numbers in k range as they are useless while(!q.isEmpty() && nums[ q.peekLast()] <= nums[i]) q.pollLast(); q.offer(i); if(i >= k - 1) r[ri++] = nums[q.peek()]; } return r; }

  方法二、

    采用兩個整形數組 leftWindow、rightWindow。

    將數組 nums 從前向後分成 n 個窗口,其中每份含有 k 個元素(最後一份可能小於 k)。

    leftWindow 存儲從左向右遍歷元素,當前窗口的最大值。rightWindow存儲從右向左遍歷元素,當前窗口的最大值。

    最終所求的窗口最大值即為: re[i] = Math.max(leftWindow(i), rightWindow[i - k + 1]) , 其中 leftWindow 與 rightWindow 分別是當前窗口的 尾部和頭部。

    public int[] maxSlidingWindow22(int[] nums, int k) {
        
        if(nums == null || k <= 0)
            return new int[0];
        
        int n = nums.length;
        int[] leftWindow = new int[n];
        leftWindow[0] = nums[0];
        int[] rightWindow = new int[n];
        rightWindow[n - 1] = nums[n - 1];
        for (int i = 1, j = n - 2; i < n; i++, j--) {
            leftWindow[i] = (i % k == 0 ? nums[i] : Math.max(nums[i], leftWindow[i-1]));
            rightWindow[j] = (j % k == 0 ? nums[j] : Math.max(nums[j], rightWindow[j + 1]));
        }

        int[] re = new int[n - k + 1];
        for (int i = k - 1, j = 0; i < n; j++, i++) 
            re[j] = Math.max(leftWindow[i], rightWindow[j]);
        return re;
    }

    

      

239. Sliding Window Maximum