Classic sliding window template question

Sliding window AcWing154


Problem : Given an array of size n≤106.

There is a sliding window of size k, which moves from the leftmost to the rightmost of the array.

You can only see k numbers in the window.

Each time the sliding window moves one position to the right.

The following is an example:

The array is [1 3 -1 -3 5 3 6 7], and k is 3.

The minimum and maximum window position
[1 3 -1] -3 5 3 6 7 -1 3
1 [3 -1 -3] 5 3 6 7 -3 3
1 3 [-1 -3 5] 3 6 7 -3 5
1 3 -1 [-3 5 3] 6 7 -3 5
1 3 -1 -3 [5 3 6] 7 3 6
1 3 -1 -3 5 [3 6 7] 3 7
Your task is to determine the sliding When the window is at each position, the maximum and minimum values ​​in the window.

Input format The
input consists of two lines.

The first line contains two integers n and k, which represent the length of the array and the length of the sliding window, respectively.

The second line has n integers, which represent the specific values ​​of the array.

Separate peer data with spaces.

Output format The
output contains two.

The first line of output, from left to right, is the minimum value in the sliding window at each position.

The second line of output, from left to right, is the maximum value in the sliding window at each position.

Input example:
8 3
1 3 -1 -3 5 3 6 7
Output example:
-1 -3 -3 -3 3 3
3 3 5 5 6 7

/*
滑动窗口——经典利用单调队列解决,用一个dequeue双端队列维护一个单调队列,队列中存储数组的索引
存储索引便于判断滑动窗口是否超出滑过而弹出队头元素
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

const int N = 1000010;
int a[N];
deque<int>windowslide;
int n, k;

void findMin(){
    
    
    //维护一个单调递减队列, 使得队头始终为滑动窗口的最小值
    windowslide.clear();
    for(int i = 0; i < n; i++){
    
    
        while( !windowslide.empty() && a[windowslide.back()] > a[i] )windowslide.pop_back();
        //若windowslide不满足单调递增,则弹出队尾元素
        while( !windowslide.empty() && i - windowslide.front() >= k )windowslide.pop_front();
        //若windowslide已滑过,则弹出队头一个元素
        windowslide.push_back(i);//添加元素
        if(i >= k - 1)cout << a[windowslide.front()] << ' ' ;//输出
    }
}

void findMax(){
    
    
    //维护一个单调递减队列, 使得队头始终为滑动窗口的最大值
    windowslide.clear();
    for(int i = 0; i < n; i++){
    
    
        while( !windowslide.empty() && a[windowslide.back()] < a[i])windowslide.pop_back();
        //若windowslide不满足单调递减,则弹出队尾元素
        while( !windowslide.empty() && i - windowslide.front() >= k)windowslide.pop_front();
        //若windowslide已滑过,则弹出队头一个元素
        windowslide.push_back(i);//add
        if(i >= k - 1)cout << a[windowslide.front()] << ' ';//output
    }
}

int main(){
    
    
    cin >> n >> k;
    for(int i = 0; i < n; i++)
        cin >> a[i];
    findMin();//找出滑动窗口的最小值
    cout << endl;
    findMax();//找出滑动窗口的最大值
    return 0;
}

Leetcode 239 Maximum sliding window

/*
	Leetcode 239滑动窗口最大值
*/

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

Guess you like

Origin blog.csdn.net/qq_45830383/article/details/108722267