滑動窗口(一):Maximum of all subarrays of size k

描述:

Given an array A and an integer K. Find the maximum for each and every contiguous subarray of size K.

Input: The first line of input contains an integer T denoting the number of test cases. The first line of each test case contains a single integer N denoting the size of array and the size of subarray K. The second line contains N space-separated integers A1, A2, ..., AN denoting the elements of the array.

Output: Print the maximum for every subarray of size k.

Constraints: 1 ≤ T ≤ 200 1 ≤ N ≤ 107 1 ≤ K ≤ N 0 ≤ A[i] <= 107

Example: Input: 2 9 3 1 2 3 1 4 5 2 3 6 10 4 8 5 10 7 9 4 15 12 90 13

Output: 3 3 4 5 5 5 6 10 10 10 15 15 90 90

Explanation: Testcase 1: Starting from first subarray of size k = 3, we have 3 as maximum. Moving the window forward, maximum element are as 3, 4, 5, 5, 5 and 6.

這個題目看描述也知道,典型的滑動窗口題目,就是給個窗口大小k,然後在這個序列上滑動,取該窗口的最大元素然後輸出。

思路:

我們用雙端隊列維護這個窗口內的所有的候選輸出,也就是說我們每次都傾向於把大的排在雙端隊列的隊頭,比如某時刻窗口內序列爲3,2,1,那麼當窗口滑動到下一個後,最大的3脫離窗口,此時2成爲output的第一候選數。

而如果某時刻窗口內爲1,2,3,那麼我們應該維護雙端隊列中3放到隊頭,把1,2都刪掉,因爲如果不這麼做,雙端隊列直接輸出隊頭1爲output,而1不是[1,2,3]中最大的。

總而言之,我們構建這樣一個雙端隊列,每次都讓窗口內最大的元素放在隊首,也就是本次窗口要輸出的最大值,然後滑動一步窗口,判斷此時隊首元素會不會脫離窗口,如果脫離,那麼讓它出隊,後面的元素頂上來,成爲要輸出最大的候選數。

代碼:

import java.util.*;
import java.io.*;
import java.lang.*;
class Solution{
    static int arr[] = new int [10000000];
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while(t-->0){
            int n = sc.nextInt();
            int k = sc.nextInt();
            for(int i=0;i<n;i++){
                arr[i]=sc.nextInt();
            }
            max_of_subarrays(n,k);
        }
    }
    static void max_of_subarrays(int n,int k){
        Deque<Integer> dq = new LinkedList<>();
        StringBuilder sb  = new StringBuilder();
        int i=0;
        for(i=0;i<k;i++){
            while(dq.isEmpty()==false&&arr[i]>=arr[dq.peekLast()])
                dq.pollLast();
            dq.addLast(i);
        }
        for(;i<n;i++){
            sb.append(arr[dq.peekFirst()]+" ");
            while(dq.isEmpty()==false&&dq.peekFirst()<=i-k)
                dq.pollFirst();
            while(dq.isEmpty()==false&&arr[i]>=arr[dq.peekLast()]){
                dq.pollLast();
            }
            dq.addLast(i);
        }
        sb.append(arr[dq.peekFirst()]);
        dq.pollFirst();
        System.out.println(sb);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章