[LintCode][Heap][Deque] Sliding Window Maximum

Problem

Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration from the start of the array, find the maximum number inside the window at each moving.

Example

For array [1, 2, 7, 7, 8], moving window size k = 3. return [7, 7, 8]At first the window is at the start of the array like this

[|1, 2, 7| ,7, 8] , return the maximum 7;

then the window move one step forward.

[1, |2, 7 ,7|, 8], return the maximum 7;

then the window move one step forward again.

[1, 2, |7, 7, 8|], return the maximum 8;

Solution

最大堆的解法。但会超时

class Solution {
public:
    /**
     * @param nums: A list of integers.
     * @return: The maximum number inside the window at each moving.
     */
    vector<int> maxSlidingWindow(vector<int> &nums, int k) {
        if (k == 0 || nums.size() == 0 || k > nums.size()) {
            vector<int> ret;
            return ret;
        }
        priority_queue<int, vector<int>> maxHeap;
        for(int i = 0; i < k; i++) {
            if (maxHeap.empty()) {
                maxHeap.push(nums[i]);
            } else {
                if (maxHeap.top() <= nums[i]) {
                    while (!maxHeap.empty()) {
                        maxHeap.pop();
                    }
                }
                maxHeap.push(nums[i]);
            }
        }
        
        vector<int> ret;
        vector<int> temp;
        int index = 0;
        for(int i = k; i < nums.size(); i++) {
            ret.push_back(maxHeap.top());
            int key = nums[index++];
            if (maxHeap.top() < nums[i]) {
                while(!maxHeap.empty()) {
                    maxHeap.pop();
                }
            }
            temp.clear();
            while(!maxHeap.empty()) {
                int element = maxHeap.top();
                maxHeap.pop();
                if (element == key) {
                    break;
                }
                temp.push_back(element);
            }
            
            for(int j = 0; j < temp.size(); j++) {
                maxHeap.push(temp[j]);
            }
            maxHeap.push(nums[i]);
        }
        ret.push_back(maxHeap.top());
        
        return ret;
    }
};

解法二:双端队列,每次pop出队尾所有小于当前元素,这样形成了一个非递增子序列。每次返回队头的最大元素。

class Solution {
public:
    /**
     * @param nums: A list of integers.
     * @return: The maximum number inside the window at each moving.
     */
    vector<int> maxSlidingWindow(vector<int> &nums, int k) {
        if (nums.size() == 0 || k == 0 || k > nums.size()) {
            vector<int> ret;
            return ret;
        }
        
        deque<int> dq;
        for(int i = 0; i < k; i++) {
            int key = nums[i];
            while (!dq.empty() && key > dq.back()) {
                dq.pop_back();
            }
            dq.push_back(key);
        }
        
        vector<int> ret;
        ret.push_back(dq.front());
        int index = 0;
        for(int i = k; i < nums.size(); i++) {
            int popElement = nums[index++];
            if (dq.front() == popElement) {
                dq.pop_front();
            }
            int key = nums[i];
            while (!dq.empty() && key > dq.back()) {
                dq.pop_back();
            }
            dq.push_back(key);
            ret.push_back(dq.front());
        }
        
        return ret;
    }
};
    原文作者:楷书
    原文地址: https://www.jianshu.com/p/c0649edcce03
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞