[Leetcode] 239. Sliding Window Maximum

Problems: https://leetcode.com/problems/sliding-window-maximum/

Solution:
利用deque,deque peek存储当前window内最大的值,实现的方法为:

  1. 当添加新unit时检查val,如果大于当前queue内的val,则将原unit pop出来,然后再加入新的unit
  2. 当添加的unit小于原来的val,则直接加入deque(因为该值有可能成为后面windows的最大值)
  3. 加入新unit的同时检查deque peek unit的index,如果超出window内的index则将该unit pop出来
class Solution {
    
    // 将index和value绑定,便于后面检查最大值是否out of window
    class Unit {
            int val;
            int idx;
            public Unit(int value, int index) {
                this.val = value;
                this.idx = index;
            }
        }
    
    public int[] maxSlidingWindow(int[] nums, int k) {
        // 利用deque
        Deque<Unit> queue = new LinkedList<>();
        int count = 0;
        int len = nums.length;
        int[] ans = new int[len-k+1];
        if(nums.length == 0) {
            return nums;
        }
        for(int i=0; i<len; i++) {
            int cur = nums[i];
            // 如果此处count <= k的话,当count == k时,deque peek存的是前四个数的最大值
            if(count < k) {
            	// 加入的值如果大于peek,则取代原来的成为新peek
                while(!queue.isEmpty() && queue.getLast().val < cur) {
                    queue.pollLast();
                }
                queue.offerLast(new Unit(cur, i));
                count++;
                if(count == k) {
                    ans[0] = queue.getFirst().val;
                }
            } else {
            	// 加入的值如果大于peek,则原来的需要被pop出来
            	// 不管这个peek是不是valid,当更大的值出现时,原来小的值一定无效
                while(!queue.isEmpty() && queue.getLast().val < cur) {
                    queue.pollLast();
                }
                // 要检查peek的index是否在window内
                if(!queue.isEmpty() && queue.getFirst().idx <= i-k) {
                    queue.pollFirst();
                }
                queue.offerLast(new Unit(cur, i));
                ans[i-k+1] = queue.getFirst().val;
            }
        }
        return ans;
    }
}

TC: O(n)
SC: O(n)
Reference: https://www.youtube.com/watch?v=uvsRkNiL0e0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值