窗口最小最大数

本文介绍了一种高效算法,用于解决滑动窗口内数组的最大值与最小值问题。通过维护双端队列来实现快速查找,适用于不同规模的数据集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意如下文所示:

 

题目描述

给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端, 你只能见到窗口的K个数,每次窗体向右移动一位,你的任务是找出窗口在各位置时的 max value,min value.

输入格式

第 1 行 n,k, 第 2 行为长度为 n 的数组

输出格式

2 行, 第 1 行每个位置的 min value, 第 2 行每个位置的 max value

样例数据

input

8 3 
1 3 -1 -3 5 3 6 7

output

-1 -3 -3 -3 3 3 
3 3 5 5 6 7

数据规模与约定

20%: n<=500;  

50%: n<=100000;

100%: n<=1000000;

时间限制:1s1s

空间限制:256MB256MB

主要思路: 控制窗户移动,进队时与现在窗户的前几个数进行比较,粗暴点来说就是把比自己小或者大(找小的挤大的,找大的挤小的)的给挤出队列,定义头指针head指队首,尾指针tail指队尾,一次次比队尾,指针指队尾(因为要挤出所以不停变换)最后这个窗户的队首一定是次窗户中最小或最大的,输出即可,但要注意空格。

#include<bits/stdc++.h>
using namespace std;
int a[1000010],zhi[1000010],n,k,head=1,tail=0;
int main()
{
    scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	 {
	 	if(i-zhi[head]>=k)head++;  //移动窗户
	 	while(a[i]<a[zhi[tail]]&&head<=tail)tail--;   //与队尾比较,如果比队尾小且还有数,则队尾指向前一个数,再进行比较
	 	zhi[++tail]=i;  // 队尾指向此数
	 	if(i>=k)   
	 	{
	 		if(i==n)   //如果i是最后一个数输出现在窗口最小数并换行
	 	      cout<<a[zhi[head]]<<endl;
	 		 else 
	 		 cout<<a[zhi[head]]<<' ';  //主要注意空格
	 	}
	 }	
	memset(zhi,0,sizeof(zhi));//指针清空,准备找窗口最大数
	head=1;tail=0;//同样回到原始
	for(int i=1;i<=n;i++)
	 {
	 	if(i-zhi[head]>=k)head++;
	 	while(a[i]>a[zhi[tail]]&&head<=tail)tail--;//与队尾比较,如果比队尾大且还有数,则队尾指向前一个数,再进行比较
	 	zhi[++tail]=i;
	 	if(i>=k)
	 	{
	 		if(i==n)
	 		cout<<a[zhi[head]]<<endl;
	 		 else 
	 		 cout<<a[zhi[head]]<<' ';
	 		//基本与找最小值一样
	 	}
	 }	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值