题目叙述:
Input:
第一行有两个数字 n 和 k。窗口大小为k。第二行输入一个数组,有 n 个整数。
数据规模:
0 < k < n <= 1,000,000
Output:
输出一共n-k+1 个数字,为窗口从左向右滑动过程中,窗口里连续k个数中的最大值。
Example:
数组为[4,3,5,4,3,3,6,7],窗口大小为3时:
[4 3 5]4 3 3 6 7
4[3 5 4]3 3 6 7
4 3[5 4 3]3 6 7
4 3 5[4 3 3]6 7
4 3 5 4[3 3 6]7
4 3 5 4 3[3 6 7]
解决思路:
(这次先只用简单数组,以后再做用指针的)
如果每次窗口移动以后,都重新找最大值,非常耗时。
用两个数 max1 和 max2 记录窗口中最大数和第二大数的指标。
窗口移动后,如果指标 max1 和 max2 都在窗口内,则将新进入窗口的数与指标为 max1 和 max2 的数进行比较,更新 max1 和 max2 的值。如果 max1 或 max2 指标已经不在窗口内,则重新对窗口内所有数进行比较找出 max1 和 max2 。
代码:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int n,k;
int i,j;
scanf("%d%d",&n,&k);
static int A[1000010]={0};
int max1=0,max2=0;//max1 is the index of the largest munber,max2 is similar.
//记录n天的钱
for(i=0;i<n;i++)
{
scanf("%d",&A[i]);
}
int left=0;//the left index of the window
//first window,find the index of max1 and max2
for(i=0;i<k;i++)
{
if(A[max1]<A[i])
{
max2=max1;
max1=i;
}
}
printf("%d ",A[max1]);
//window move
while(left<n-k)
{
if(left==max1||left==max2)
{
left++;
max1=max2=left;
for(i=0;i<k;i++)
{
if(A[max1]<A[left+i])
{
max2=max1;
max1=left+i;
}
}
printf("%d ",A[max1]);
}
else
{
left++;
if(A[max1]<A[left+k-1])
{
max2=max1;
max1=left+k-1;
}
else
{
if(A[max2]<A[left+k-1])
{
max2=left+k-1;
}
}
printf("%d ",A[max1]);
}
}
}
结语:
因为不熟悉用指针等其他的方法,所以先用简单数组做一下,比每次窗口移动都重新比较的方法(第一次这样做,提交作业没成功),用简单数组和两个指标可以提高八九倍的运行速度(第二次过了)。
以后做了更多再继续补充。