[leetcode] 239. Sliding Window Maximum

来源:互联网 发布:淘宝哪家情侣装好看 编辑:程序博客网 时间:2024/05/24 05:20

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

Window position                Max---------------               -----[1  3  -1] -3  5  3  6  7       3 1 [3  -1  -3] 5  3  6  7       3 1  3 [-1  -3  5] 3  6  7       5 1  3  -1 [-3  5  3] 6  7       5 1  3  -1  -3 [5  3  6] 7       6 1  3  -1  -3  5 [3  6  7]      7

Therefore, return the max sliding window as [3,3,5,5,6,7].

Note: 
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

Follow up:
Could you solve it in linear time?

Hint:

  1. How about using a data structure such as deque (double-ended queue)?
  2. The queue size need not be the same as the window’s size.
  3. Remove redundant elements and the queue should store only elements that need to be considered.

这道题是找滑动窗口中的最大值,题目难度为Hard。


提示已经基本说出了解题思路,假设滑动窗口移动到了第m个数字,那它之前的数字哪些是需要记录下来以备后续比较使用的呢?第m-k+1个数字之前的数字不在窗口内,所以是不用考虑的,而在第m-k+1到第m个数字之间的k个数中,哪些又是不必考虑的呢?窗口移动到第m个数字时,和第m个数字左相邻的数字如果比第m个数字小,那它在移出窗口之前会一直和第m个数字同时在窗口中,所以它是不需要考虑的,也就没必要存储了,这样一直向左直至找到比第m个数字大的数字(假定为第n个数字),第n到第m之间的数字都是不需要考虑的,最终存储下来的数字会呈现出递减的趋势,也就是说存储的第一个数字即是窗口中最大的数字。如果马上移出窗口的数字等于存储的最大数字(相等数字也照顾到了),说明当前窗口中最大的数字在窗口最左端,马上要移出窗口,所以需要删除存储的第一个数字。既然在首部和尾部都需要删除数据,所以我们选择双端队列来存储数据。依照上面介绍的方法顺序遍历数组,在遍历到第k个数字之后每次遍历时将队列首部的数据存入最终结果即可。具体代码:

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        deque<int> window;        vector<int> ret;        for(int i=0; i<nums.size(); ++i) {            while(!window.empty() && window.back() < nums[i]) {                window.pop_back();            }            window.push_back(nums[i]);            if(i >= k-1) {                if(i != k-1 && nums[i-k] == window.front()) window.pop_front();                ret.push_back(window.front());            }        }        return ret;    }};

0 0