[Leetcode 239, Hard] Sliding Window Maximum

Problem:

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.

Analysis:

A very interesting question!


The meaning of window implies that the element whose index is smaller than the left end of a window should be discarded. By the language of array, a maximal value whose index is i in this question is a local maximal value ranging from i - k + 1 to i + k -1. Then, the maximal value of a window may become smaller, since the last maximal value has expired (its index is smaller than the start index of the window). Thus, the brute-force method does not work for this problem.


An alternative method is that we use pairs, value and its index, to fill into window. The index value indicates whether this value (the front entry of the window indicates the maximal value of the current window) has expired. Before updating the information of the window, we first check a value has expired. When adding candidate maximal values, we use decremental add, which mean that we will discard the candidates which is samller than the new one. This is valid because they will not have a chance to be the maximal ones, since they will not be bigger than the new one and they are in the range covered by the new candidate.


This problem contains usful message in engineering.

Solutions:

C++:

    void DecrementalAdd(deque<pair<int, int> >& window, pair<int, int> value_pair)
    {
        while(!window.empty()) {
            if(window.back().first < value_pair.first)
                window.pop_back();
            else {
                window.push_back(value_pair);
                break;
            }
        }
        if(window.empty())
            window.push_back(value_pair);
    }

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> max_values;
        if(nums.empty() || k == 0)
            return max_values;

        int start = 0;
        int end = start + k - 1;
        deque<pair<int, int> > window;
        for(int i = start; i <= end; ++i) { //Initialization.
            if(i == start)
                window.push_back(make_pair(nums[i], i));
            else {
                if(window.back().first < nums[i]) {
                    DecrementalAdd(window, make_pair(nums[i], i));
                } else if(window.size() < k)
                    window.push_back(make_pair(nums[i], i));
            }
        }
        
        max_values.push_back(window.front().first);
        
        for(++start, ++end; end < nums.size(); ++start, ++end) {
            if(window.front().second < start)
                window.pop_front();
                
            if(window.empty())
                window.push_back(make_pair(nums[end], end));
            else if(window.size() < k)
                DecrementalAdd(window, make_pair(nums[end], end));

            max_values.push_back(window.front().first);
        }
        
        return max_values;
    }
Java:


Python:

發佈了194 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章