Sliding Window

Sliding Window

https://ac.nowcoder.com/acm/problem/51001

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

An array of size n ≤ 106 is given to you. 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 rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position Minimum value Maximum value
[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 maximum and minimum values in the sliding window at each position.

输入描述:

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.

输出描述:

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
示例1

输入

复制
8 3
1 3 -1 -3 5 3 6 7

输出

复制
-1 -3 -3 -3 3 3
3 3 5 5 6 7
Sliding Window
返回全部题目
列表加载中...

题目描述

给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,你的任务是找出窗体在各个位置时的最大值和最小值。

解题思路

单调队列的经典题目,正如邓老师说的那样,每次区间滑动一个单位,区间内元素从图片说明
变为了图片说明 可以看出,变化的部分,只有a[l]和a[r+1],完全没必要把中间部分去遍历很多遍。
这时候就请来了强大的单调队列大大,开辟一个队列,让里面保存的都是可能是答案的下标,并且当前位置的答案下标保存在对头中。
具体的实现过程注释的比较详细,当前元素如果要入队,之前的对头下标如果和自己差距大于m,说明以前的下标不合法了,队头出队。
拿求最小值来说,如果队尾元素大于等于当前a[i],a[i]入队后,最小值不可能是当前队尾了,队尾元素出队。反复循环直到队尾元素小于a[i]。
可以用手动模拟尽可能用手动,deque的话常数比手动大,有时候会被卡)我竟然被卡过……

Code

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;

inline int read() {
    int s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}

const int N = 1e6 + 7;
int a[N], que[N];

int main() {
    int n = read(), m = read();
    for (int i = 1; i <= n; ++i)
        a[i] = read();
    int l = 0, r = 0; //单调队列队头和队尾
    que[r++] = 1;
    if (m == 1)    printf("%d ", a[1]); //后面从2开始特判下m
    for (int i = 2; i <= n; ++i) {
        //队中存在元素,并且之前的最小元素下标已经不在当前m范围内 出队
        if (r > l && i - que[l] >= m)    ++l;
        //  当前队尾值大于等于a[i] a[i]入队后,最小值一定不会是队尾了,队尾出队
        while (r > l && a[que[r - 1]] >= a[i])    --r;

        que[r++] = i;
        if (i >= m)
            printf("%d ", a[que[l]]); //队头中保存的就是最小值下标位置
    }
    puts("");
    // 最大值类似
    l = r = 0;
    que[r++] = 1;
    if (m == 1)    printf("%d ", a[1]);
    for (int i = 2; i <= n; ++i) {
        //队中存在元素,并且之前的最大元素下标已经不在当前m范围内 出队
        if (r > l && i - que[l] >= m)    ++l;
        //  当前队尾值小于等于a[i] a[i]入队后,最大值一定不会是队尾了,队尾出队
        while (r > l && a[que[r - 1]] <= a[i])    --r;

        que[r++] = i;
        if (i >= m)
            printf("%d ", a[que[l]]); //队头中保存的就是最大值下标位置
    }
    puts("");
    return  0;
}
牛客算法竞赛入门课 文章被收录于专栏

给雨巨打call

全部评论

相关推荐

new和malloc的区别?c++里new了数组怎么释放?32位系统的指针变量占多大字节?int*呢?空类呢?c++多态?为什么需要虚析构?虚析构实现原理?c++可以不写构造函数吗?编译器默认除了构造还会有什么?深拷贝和浅拷贝区别?智能指针哪个c++版本引入的,作用?用过哪些容器?项目里用了哪些容器?为什么用qlist?qmap什么是key?模板的好处?什么时候会用?设计模式了解哪些?自己写过吗?单例模式怎么写?单例要返回非静态指针类型怎么弄?队列和栈的区别?osi七层以及相应协议?网络层的协议?应用层?一些项目问题...网络加密算法知道哪些?tcp的三次握手四次挥手回收写过吗?写服务器基本模...
AI牛可乐:哇,你分享了好多面试经验呢,听起来你准备得很充分呢!👍 关于你提到的技术问题,我来帮你解答一下吧: 1. `new` 和 `malloc` 的区别?`new` 会自动调用构造函数,而 `malloc` 只负责分配内存。`new` 数组释放时用 `delete[]`,比如 `delete[] myArray;`。 2. 在32位系统中,指针变量通常占4个字节,`int*` 也是如此。 3. 空类的实例通常占1个字节,但具体实现可能不同。 4. C++多态允许我们通过基类指针或引用来调用派生类的函数。需要虚析构是因为基类指针可能指向派生类对象,不使用虚析构可能导致派生类析构函数不被调用。 5. 如果不写构造函数,编译器会提供一个默认构造函数。默认构造函数会进行成员变量的默认初始化。 6. 深拷贝和浅拷贝的区别在于,深拷贝会复制对象的所有字段,包括指向的内存内容;浅拷贝只复制对象的字段值,不复制指向的内存内容。 7. 智能指针是在C++11版本引入的,用于自动管理内存,防止内存泄漏。 8. 常用的容器有 `vector`、`list`、`map` 等。具体使用哪个容器取决于项目需求。 关于你问的其他问题,我简单回答一下: - `QList` 通常用于需要频繁插入和删除的场景。 - `QMap` 的 `key` 是映射表中的键值。 - 模板的好处是提高代码复用性,减少代码冗余。 - 设计模式有很多种,比如单例模式、工厂模式等。单例模式可以通过静态成员函数实现。 现在,悄悄告诉你一个小秘密,点击我的头像,我们可以私信聊天哦~🎉 那么,你平时在项目中都用过哪些容器呢?有没有什么特别的经验或者技巧可以分享的呢?😊
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务