| Time Limit: 12000MS | Memory Limit: 65536K | |
| Total Submissions: 33379 | Accepted: 9924 | |
| Case Time Limit: 5000MS | ||
Description
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.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
题意:
给定含有n个元素的无序序列a[],和一个整数k,要求求出a[]中,从左向右每连续k个元素组成的序列中的最小值(或最大值),这样的值可能有1个或n-k+1个。
思路:
利用单调队列来求解,需要注意的是,单调队列的最大长度为k。单调队列
代码:
#include <stdio.h>
#define MAXN 1000000
int mq[MAXN+5]; //单调队列,存储元素的索引
int f; //队首指针
int r; //队尾指针
int a[MAXN+5]; //数字串
int n; //数字个数
int k; //滑动窗口大小
void Push_Asc(int i) //按升序进队
{
while (r > f && a[i] < a[mq[r-1]])
{
r--;
}
mq[r++] = i;
}
void Push_Desc(int i) //按降序进队
{
while (r > f && a[i] > a[mq[r-1]])
{
r--;
}
mq[r++] = i;
}
inline int Front(void)
{
return mq[f];
}
inline bool IsEmpty(void)
{
return f == r;
}
inline void Pop(void)
{
f++;
}
void SlidingWindow(bool ascending)
{
f = r = 0; //初始化队列
void (*Push)(int) = ascending ? Push_Asc : Push_Desc; //判断单调队列是上升还是下降
int i;
for (i = 1; i <= k && i <= n; i++) //让前k个数进队,k有可能大于n
{
Push(i);
}
printf("%d", a[Front()]);
for (; i <= n; i++)
{
while (!IsEmpty() && Front() + k <= i) //弹出不在滑动窗口内的元素
{
Pop();
}
Push(i);
printf(" %d", a[Front()]);
}
putchar('\n');
}
int main(void)
{
while (scanf("%d%d", &n, &k) != EOF)
{
int i;
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
SlidingWindow(true);
SlidingWindow(false);
}
return 0;
}
1967



被折叠的 条评论
为什么被折叠?



