[Sword finger offer] _19 The maximum value in the sliding window

Title description

Given the size of an array and sliding windows, find the maximum value of all sliding windows. For example, if the input array {2,3,4,2,6,2,5,1} and the size of the sliding window are 3, then there are a total of 6 sliding windows, and their maximum values ​​are {4,4,6, 6,6,5}; The sliding window for the array {2,3,4,2,6,2,5,1} has the following 6: {[2,3,4], 2,6,2,5 , 1}, {2, [3,4,2], 6,2,5,1}, {2,3, [4,2,6], 2,5,1}, {2,3,4 , [2,6,2], 5,1}, {2,3,4,2, [6,2,5], 1}, {2,3,4,2,6, [2,5, 1]}.

Problem-solving ideas

  1. Solution 1: Brute force method, sequential block scanning. For example, in the above example, we continue to group and search, a group of 3, so that eventually it will find its maximum value. But its time complexity is O (NK). N is the number of sliding windows, and K is the size of the sliding window.
  2. Option 2: Double-ended queue implementation. Since the steps implemented in scheme two are more complicated, we have changed the way of thinking. In the process of obtaining the maximum value, we do not store each value in the queue, but only store the data that may become the maximum value. To the deque at both ends, the above input is used as an example, and the solution process is as follows:

Insert picture description here

Code

class Solution {
    vector<int> res;
    deque<int> q;
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        if(num.size()>=size && size >= 1)  //保证参数合理性
        {
            //取一个窗口中的最大值的下标
            for(int i=0;i<size;++i)
            {
                if(!q.empty() && num[q.back()]<=num[i])
                    q.pop_back();
                q.push_back(i);
            }
            
            //处理后面
            for(int i = size;i<num.size();++i)
            {
                //每回将一个窗口中的最大值压入结果集合
                //最大值永远是以队列头元素为下标的值
                res.push_back(num[q.front()]);
                
                //如果后面元素大小有比以队列中任何一个元素为下标的元素大的话
                //把队列清空
                while(!q.empty() && num[q.back()] <= num[i])
                    q.pop_back();
                
                //如果后面的元素没有比当前最大元素大,但是窗口已经满了,滑过了最大元素的下标
                if(!q.empty() && q.front() <= i-size)
                    q.pop_front();
                q.push_back(i);
            }
            //最后一次循环结束,i到头,最后一个窗口中的最大值就是
            //以队列中头元素为下标的值
            res.push_back(num[q.front()]);
        }
        return res;
    }
};
Published 253 original articles · praised 41 · 40,000+ views

Guess you like

Origin blog.csdn.net/liuyuchen282828/article/details/104207382