题目描述
给定一个大小为n≤106的数组。
有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。
您只能在窗口中看到k个数字。
每次滑动窗口向右移动一个位置。
以下是一个例子:
该数组为[1 3 -1 -3 5 3 6 7],k为3。
窗口位置 最小值 最大值
[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
您的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。
输入格式
输入包含两行。
第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长度。
第二行有n个整数,代表数组的具体数值。
同行数据之间用空格隔开。
输出格式
输出包含两个。
第一行输出,从左至右,每个位置滑动窗口中的最小值。
第二行输出,从左至右,每个位置滑动窗口中的最大值。
样例
输入样例:
8 3
1 3 -1 -3 5 3 6 7
输出样例:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
C++ 代码
#include<iostream>
#include<cstring>
int ali[1000007] = {};
int love[1000007] = {};
int head = 0, tail = -1;
int N, K;
int main(void)
{
std::ios_base::sync_with_stdio(false);
std::cin >> N >> K;
for (int i = 0; i < N; i++)std::cin >> ali[i];
//show_min
for (int i = 0; i < N; i++)
{
while(i - K + 1 > love[head])head++;
//love数组储存的是ali数组的下标,若没有head <= tail判断,会有bug,
//当i=1,K=1时,love[head]等于0时,接下来的ali数组的值均为0,然后head
//就会无限递增或者把while改为if,因为每次位移是1,所以若有出界元素,也
//只可能是一个
while (head <= tail && ali[love[tail]] >= ali[i])tail--;
love[++tail] = i;
if (i - K >= -1)printf("%d ", ali[love[head]]);
}
//show_max
memset(love, 0, sizeof(love));
putchar('\n');
head = 0, tail = -1;
for (int i = 0; i < N; i++)
{
if(head <= tail && i - K + 1 > love[head])head++;
while (head <= tail && ali[love[tail]] <= ali[i])tail--;
love[++tail] = i;
if (i - K >= -1)printf("%d ", ali[love[head]]);
}
return 0;
}
…你是不是把题解写错了地方hh
啊这。。
…你是不是把题解写错了地方hh