【数据结构与算法】单调队列结构解决滑动窗口问题

197 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

接下来的时间里,Sivan带着大家一起学习数据结构与算法哟!

单调队列结构解决滑动窗口问题

单调队列这个数据结构主要可以解决滑动窗口相关的问题。

LeetCode 239

image.png 使用单调队列,由于单调队列的特点先进先出,对头尾进行操作,所以单调队列内部使用双链表LinkedList实现头尾的增减。


class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //利用单调队列的先进先出特点。
        MonotonicQueue window = new MonotonicQueue();
        //保存结果
        List <Integer> res = new ArrayList<>();
        for(int i = 0;i<nums.length;i++){
            if(i < k-1 ){
                //先把当前窗口内的元素加入。
                window.push(nums[i]);
            }else {
                //窗口向前滑动
                //移入新元素
                window.push(nums[i]);
                res.add(window.max());
                //移出窗口内的最后一个元素
                window.pop(nums[i-k+1]);
            }
        }
        //ArrayList转换为int数组
        int [] ret = new int [res.size()];
        for(int i=0;i<res.size();i++){
            ret[i] = res.get(i);
        }
        return ret;
    }
//构建单调队列数据结构
class MonotonicQueue{
    //LinkedList底层使用双向链表
    private LinkedList <Integer> q =new LinkedList<>();
    //加入元素
    public void push(int nums){
        //删除所有小于nums的值。
        while(!q.isEmpty() && q.getLast()<nums){
            q.pollLast();
        }
        q.addLast(nums);
    }
    //获取当前窗口内最大元素。
    public int max(){
        return q.getFirst();
    }
    //移出元素
    public void pop(int nums){
        if(nums == q.getFirst()){
            q.pollFirst();
        }
    }
}
}