算法-15生成窗口最大值数组

描述

有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置,求每一种窗口状态下的最大值。(如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值)
 

输入描述:

第一行输入n和w,分别代表数组长度和窗口大小
第二行输入n个整数X_iXi,表示数组中的各个元素

输出描述:

输出一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值

示例1

复制代码
输入:
8 3
4 3 5 4 3 3 6 7

输出:
5 5 5 4 6 7

说明:
例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时:

[4 3 5] 4 3 3 6 7        窗口中最大值为5

4 [3 5 4] 3 3 6 7        窗口中最大值为5

4 3 [5 4 3] 3 6 7        窗口中最大值为5

4 3 5 [4 3 3] 6 7        窗口中最大值为4

4 3 5 4 [3 3 6] 7        窗口中最大值为6

4 3 5 4 3 [3 6 7]        窗口中最大值为7

输出的结果为{5 5 5 4 6 7}
复制代码

思路

使用双端队列来记录一个窗口中,arr 数组的最大值序号。
复制代码
import java.util.LinkedList;
import java.util.Scanner;

public class Main{
    
    // 双端队列始终维持一个前大后小的结构,随着窗口右移,队列前面的元素会失效
    // 维护队列:如果队尾对应的元素小,弹出不要;如果队尾对应元素大,就把新的数组的下标加进来,继续维护前大后小的结构
    public static int[] getMaxWindow(int[] arr,int w) {
        if(arr == null || w<1||arr.length<w){
            return null;
        }
        //结果为n-w+1长度的数组
        LinkedList<Integer> qMax = new LinkedList<Integer>();
        int[] result = new int[arr.length - w +1];
        int index = 0;
        for(int i=0;i<arr.length;i++){
            // 如果队尾对应的元素比较小,就弹出队尾,直到队尾的位置所代表的值比当前值arr[i]大
            while(!qMax.isEmpty()&&arr[qMax.peekLast()] <= arr[i]) {
                qMax.pollLast();
            }
            qMax.addLast(i);
            
            // 检查队头下标是否过期,过期就把队头弹出
            if(qMax.peekFirst() == i - w){
                qMax.pollFirst();
            }
            // 如果窗口出现了,就开始记录每个窗口的最大值
            if(i >= w -1) {
                result[index++] = arr[qMax.peekFirst()];
            }
        }
        return result;
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int w = scanner.nextInt();
        int[] arr = new int[n];
        int i = 0;
        while(scanner.hasNext()){
            arr[i++] = scanner.nextInt();
        }
        
        int[] res = getMaxWindow(arr,w);
        StringBuilder sb = new StringBuilder();
        for(int data : res){
            sb.append(data).append(" ");
        }
        System.out.println(sb);
        
    }
    
}
复制代码

 

posted @   思凡念真  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示