滑动窗口(一):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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章