122. 滑动窗口最大值(卡码网周赛第二十期(23年用友提前批笔试真题))

122. 滑动窗口最大值(卡码网周赛第二十期(23年用友提前批笔试真题))

题目描述

给定一个整数数组 nums 和一个整数 k,k 表示滑动窗口的大小。你需要找出每个滑动窗口中的最大值与最小值的差,并返回这些差的最大值。

输入

数组的长度为 n,1 <= n <= 10000,数组中的每个元素范围为[-10000,10000],滑动窗口大小k的范围为[1,n]。

输出

例如,给定一个字符串 “nums = [1,3,-1,-3,5,3,6,7], k = 3”,表示一个数组和窗口大小 k。对于该数组中的每个窗口,计算最大值与最小值的差,并返回这些差值中的最大值。
在这个例子中,每个窗口的最大值与最小值的差分别为 [4, 6, 8, 8, 3, 4],因此最终返回的结果是 8。

样例输入

nums = [1,3,-1,-3,5,3,6,7], k = 3

样例输出

8

提示

题目输入是一个字符串,需要自己解析为数组和 k 值。

题解1(C++版本)

#include<bits/stdc++.h>
using namespace std;

const int N = 1e4 + 10;
char s[N];
int n, k, a[N], mi[N], mx[N], q1[N], q2[N];

void getMax(){ //队头保存最大值 
	int h1 = 1, t1 = 0; //清空队列
	for(int i = 1; i <= n; i++){
		while(h1 <= t1 && a[q1[t1]] <= a[i]) t1--; //队尾出队 
		q1[++t1] = i; //队尾入队 
		if(q1[h1] < i - k + 1) h1++; //队头出队 
		if(i >= k) { // 使用最值 
			mx[i] = a[q1[h1]];
		}
	} 
}

void getMin(){ //队头保存最小值 
	int h2 = 1, t2 = 0; //清空队列
	for(int i = 1; i <= n; i++){
		while(h2 <= t2 && a[q2[t2]] >= a[i]) t2--; //队尾出队 
		q2[++t2] = i; //队尾入队 
		if(q2[h2] < i - k + 1) h2++; //队头出队 
		if(i >= k) { // 使用最值 
			mi[i] = a[q2[h2]];
		}
	} 
}

void read(){
    scanf("%[^\n]", s + 1); //读取一行字符串,直到读取到换行符为止
	int len = strlen(s + 1);
    int flag = 1, num = 0;
	int i = 1;
	
	for(; i <= len; i++){ // 读取数组中的元素
	    if(s[i] == '[') {
	        continue;
	    }else if(s[i] == ']'){ // 读取最后一个数组元素
	        a[++n] = num * flag;
	        num = 0;
	        flag = 1;
	        break;
	    }
	    if(s[i] == '-'){
	        flag = -1;
	    }else if(s[i] >= '0' && s[i] <= '9'){
	        num = num * 10 + s[i] - '0';
	    }else if(s[i] == ','){ 
	        a[++n] = num * flag;
	        num = 0;
	        flag = 1;
	    }
	}
	
	for(; i <= len; i++){ // 读取k
	    if(s[i] >= '0' && s[i] <= '9'){
	        k = k*10 + s[i] - '0';
	    }
	}
}
int main(){
	read(); // 读取数据
	getMin();getMax();
	int ans = 0;
	for(int i = k; i <= n; i++){
	    ans = max(ans, mx[i] - mi[i]);
	}
	printf("%d\n", ans);
	return 0;
}
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值