题解 | #滑动窗口的最大值#

滑动窗口的最大值

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

此问题的暴力解法,O(N*M),不能通过

O(N), O(N)

需要借助于双端队列进行操作,维护队列中元素为不严格单调递降,即单调队列

思路分析:打个比方,给定num = [1,3,3,2,1 ],size = 3,第一个窗口中,1,3,3 中最大值为3,然后滑动到第二个窗口,3,3,2最大值为3,我们只需要在队列中维护,窗口滑动过程中,最有可能成为最大值的可能,即不严格单调递降。因此,第一窗口时,队列中维护3,3,第二个窗口时,队列3,3,2,第三个窗口时,队列3,2,1,最大值都是队列的第一个

题外话,此题求窗口最大值,所以维护不严格单调递降,若是窗口最小值,维护队列为不严格单调递增即可

其中最为主要的两个操作,都是为了维护队列

1,维护队列中元素不严格单调递减

2,维护队列,让队列中的值,只含有此窗口中的元素,相当于判断队列中的头元素是否应该剔除,

import java.util.*;
public class Solution {//单调队列,队列中不严格递降
public ArrayList<Integer> maxInWindows(int [] num, int size) {
    ArrayList<Integer> res = new ArrayList<>();
    Deque<Integer> deque = new LinkedList<>();
    for(int i = 0; i < size; i++){//先将前size个元素,加入队列
        while(!deque.isEmpty() && deque.peekLast() < num[i]){//更新队列,保证队列元素不严格递降,操作1
            deque.pollLast();
        }
        deque.add(num[i]);
    }
    
    res.add(deque.peekFirst());
    
    for(int i = size; i < num.length; i++){
        
        if(!deque.isEmpty() && deque.peekFirst() == num[i - size]){//更新队列,判断队列中的头元素是否应该剔除,操作2
            deque.pollFirst();
        }
        
        while(!deque.isEmpty() && deque.peekLast() < num[i]){//加入元素,更新队列,操作1
            deque.pollLast();
        }
        deque.add(num[i]);
        
        res.add(deque.peekFirst());  
    }
    return res;
}
}
全部评论

相关推荐

孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务