滑动窗口的最大值(堆+双指针,不用remove)

滑动窗口的最大值

http://www.nowcoder.com/questionTerminal/1624bc35a45c42c0bc17d17fa0cba788

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
窗口大于数组长度的时候,返回空

示例1

输入
[2,3,4,2,6,2,5,1],3
返回值
[4,4,6,6,6,5]

思路

1.使用大顶堆保存数据。同时保持两个指针in和out,out指向即将离开窗口的位置,in指向即将进入窗口的位置。
2.流程:首先,每当窗口就位后,从大顶堆中取出堆顶元素放入结果列表中;然后比较堆顶元素和out指向元素的大小,如果相等,就将堆顶元素pop掉,不相等就不pop;接着将in指向的元素入队;最后out++,in++;
3.上述流程是从最小栈那题借鉴来的。和现有的使用堆删除语句的题解比较,本题解虽然空间开销大(堆会保存已遍历过的所有小等于目前窗口中最大值的值),但是时间开销小,主要是避免了remove带来的开销。

code

import java.util.*;
public class Solution {
    PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
        public int compare(Integer o1,Integer o2){
            return o2.compareTo(o1);
        }
    });
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        ArrayList<Integer> res = new ArrayList<>();
        if(num==null || num.length==0 || size>num.length || size<=0) return res;
        for(int i=0;i<size;i++) pq.add(num[i]);
        int pointer_out = 0,pointer_in = size;
        while(pointer_in <= num.length){
            res.add(pq.peek());
            if(pq.peek()==num[pointer_out++]) pq.poll();
            if(pointer_in < num.length) pq.add(num[pointer_in]);
            pointer_in++;
        }

        return res;
    }
}
全部评论
14,15,13,12,11,最后一个窗口的最大值是14
点赞 回复 分享
发布于 2021-03-19 09:28

相关推荐

昨天 17:48
中山大学 C++
点赞 评论 收藏
分享
11-18 09:44
Java
小白也想要offer:简历别放洋屁,搞不还还放错了,当然你投外企除外,以上纯属个人观点
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务