Tuesday, July 12, 2016

Sliding Window Maximum -- LeetCode 239

[Question]
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].

[Analysis]
There are a few solutions for this question:
1. For each sliding window, scan and find the maximum number. The time complexity is O(K * (N-K)).
2. For each sliding window. maintain a max heap -- pop() and push() while sliding window moves. The time complexity is ( K + logK * (N-K) );
3. Using the "Max-Queue" (the maximum/minimum value of queue) to track the possible maximum in the sliding window. The time complexity is O(N);

The cold below is for the 3rd solution. A STL "list" is used as a Deque. A STL "queue" (std::queue<int, std::list<int>>) can be used also as long as the underlying container is linked list based, to reduce the cost of memory copying.

[Solution]
class Solution {
    list<int> deque;
    void deque_append(int a) {
        for (int k=deque.size(); k>0; k--) {
            if (deque.back()<a) deque.pop_back();
        }
        deque.push_back(a);
    }
public:  
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if (nums.size()==0) return vector<int>();
        vector<int> rslt;
       
        for(int i=0; i<k; i++) {
            deque_append(nums[i]);
        }
        rslt.push_back(deque.front());
       
        for (int i=k; i<nums.size(); i++) {
            if (deque.front() == nums[i-k]) deque.pop_front();
            deque_append(nums[i]);
            rslt.push_back(deque.front());           
        }
        return rslt;
    }
};

No comments:

Post a Comment