zoukankan      html  css  js  c++  java
  • 滑动窗口的最大值


    给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组 {2,3,4,2,6,2,5,1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4,4,6,6,6,5};针对数组 {2,3,4,2,6,2,5,1} 的滑动窗口有以下 6 个:{[2,3,4],2,6,2,5,1},{2,[3,4,2],6,2,5,1},{2,3,[4,2,6],2,5,1},{2,3,4,[2,6,2],5,1},{2,3,4,2,[6,2,5],1},{2,3,4,2,6,[2,5,1]}。
    窗口大于数组长度的时候,返回空


    解题思路

    最简单的思路就是使用双指针 + 优先级队列

    import java.util.PriorityQueue;
    import java.util.Comparator;
    import java.util.ArrayList;
    public class Solution {
        
        private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(3, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        
        public ArrayList<Integer> maxInWindows(int [] num, int size) {
            ArrayList<Integer> list = new ArrayList<>();
            if(num.length == 0 || num.length < size) {
                return list;
            }
            int low = 0;
            int high = low + size - 1;
            while(high <= num.length - 1) {
                for(int i = low; i <= high; i++) {
                    maxHeap.offer(num[i]);
                }
                Integer result = maxHeap.poll();
                if(result != null) {
                    list.add(result);
                }
                maxHeap.clear();
                low++;
                high++;
            }
            return list;
        }
    }
    

    第二种思路就是使用双端队列,遍历数组,对于每一个新加进来的元素,都先判断是否比队尾的元素大,这样一来队列头保存的肯定就是当前滑动窗口中最大的值了。在弹出队头元素时,还要判断一下元素是否过期

    import java.util.*;
    public class Solution {
        public ArrayList<Integer> maxInWindows(int [] num, int size) {
            if (num == null || num.length == 0 || size <= 0 || num.length < size) {
                return new ArrayList<Integer>();
            }
            ArrayList<Integer> result = new ArrayList<>();
            // 双端队列,用来记录每个窗口的最大值下标
            LinkedList<Integer> qmax = new LinkedList<>();
            int index = 0;
            for (int i = 0; i < num.length; i++) {
                while (!qmax.isEmpty() && num[qmax.peekLast()] < num[i]) {
                    qmax.pollLast();
                }
                qmax.addLast(i);
                //判断队首元素是否过期
                if (qmax.peekFirst() == i - size) {
                    qmax.pollFirst();
                }
                //向result列表中加入元素
                if (i >= size - 1) {
                    result.add(num[qmax.peekFirst()]);
                }
            }
            return result;
        }
    }
    

  • 相关阅读:
    生成函数学习笔记
    CF1437F Emotional Fishermen
    BZOJ 1443 [JSOI2009]游戏Game
    BZOJ 1018 [SHOI2008]堵塞的交通traffic
    访问量破1000之记录
    BZOJ 1022 [SHOI2008]小约翰的游戏John
    BZOJ1457 棋盘游戏
    BZOJ1874: [BeiJing2009 WinterCamp]取石子游戏
    BZOJ 1188 [HNOI2007]分裂游戏
    Codeforces Round #345 (Div. 2)
  • 原文地址:https://www.cnblogs.com/Yee-Q/p/14230248.html
Copyright © 2011-2022 走看看