首页 > 试题广场 >

【模板】滑动窗口

[编程题]【模板】滑动窗口
  • 热度指数:2225 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}给定一个长度为 n 的整数数组 a 和一个窗口大小 k (1\leqq k\leqq n)。滑动窗口从左到右移动,每次右移一位(窗口覆盖下标 [i,i+k-1])。对于数组的每一个窗口位置,求出窗口内元素的最大值。

输入描述:
\hspace{15pt}第一行输入两个整数 n,k\left(1\leqq k\leqq n\leqq 2\times10^{5}\right)
\hspace{15pt}第二行输入 n 个整数 a_1,a_2,\dots ,a_n,元素范围 1 \leqq a_i \leqq 10^{9}


输出描述:
\hspace{15pt}输出共 n-k+1 个整数,为每个滑动窗口的最大值,数之间以单个空格分隔。
示例1

输入

10 3
2 13 6 19 15 13 17 9 19 13

输出

13 19 19 19 17 17 19 19
示例2

输入

10 1
13 13 5 3 9 19 18 4 17 3

输出

13 13 5 3 9 19 18 4 17 3
示例3

输入

10 10
15 20 5 20 19 1 4 18 14 15

输出

20
import java.util.*;

import java.io.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        String[] lineone=bf.readLine().split(" ");
        String[] linetwo=bf.readLine().split(" ");
        int n=Integer.parseInt(lineone[0]),k=Integer.parseInt(lineone[1]);
        int[] arr=Arrays.stream(linetwo).mapToInt(Integer::parseInt).toArray();
        Deque<Integer> dq=new LinkedList<>();//维护单调队列
        StringJoiner sj=new StringJoiner(" ");

        for(int i=0;i<n;i++){
            //单调递减
            while(!dq.isEmpty()&&arr[dq.peekLast()]<=arr[i]){
                dq.pollLast();//队尾安全出队
            }
            dq.offerLast(i);

            //如果队首划过窗口则移除
            if(dq.peekFirst()<=i-k){
                dq.pollFirst();
            }

            //够窗口大小时收集元素
            if(i>=k-1){
                sj.add(arr[dq.peekFirst()]+"");
            }
        }
        System.out.println(sj.toString());
        
    }
}

发表于 2025-08-24 18:05:55 回复(0)