Leetcode 239.滑动窗口的最大值

239. 滑动窗口最大值

先使用双向链表构建一个单调递减队列,有三个方法:

  • push 在队尾添加元素,但要将前面比它小的元素删除。
  • max 返回最大元素,即队头
  • pop 若元素为队头,则删除(判断是因为有可能被压扁了,已经不存在了)

然后,遍历数组,先把队列前 k - 1 个填满,再开始向前滑动移入新元素,再记录最大值,再移出旧元素。

public class Solution {
    
    class MonotonicQueue {
        // 双链表,支持头部和尾部增删元素
        LinkedList<Integer> q = new LinkedList();
        
        public void push(int val) {
            // 将前面小于自己的元素都删除
            while (!q.isEmpty() && q.getLast() < val) q.pollLast();
            q.addLast(val);
        }
        
        public int max() {
            return q.getFirst();
        }
        
        public void pop(int val) {
            // 因为我们想删除的队头元素 val 可能已经不存在了,所以这时候就不用删除了
            if (val == q.getFirst()) q.pollFirst();
        }
    }
    
    public ArrayList<Integer> maxInWindows(int[] num, int k) {
        ArrayList<Integer> res = new ArrayList();
        if (k == 0) return res;
        
        MonotonicQueue w = new MonotonicQueue();
        for (int i = 0; i < num.length; i++) {
            //先填满窗口的前 k - 1
            if (i < k - 1) w.push(num[i]);
            else {
                // 窗口向前滑动,加入新数字
                w.push(num[i]);
                // 记录当前窗口的最大值
                res.add(w.max());
                // 移出旧数字
                w.pop(num[i - k + 1]);
            }
        }
 
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值