前言
滑动窗口是一种算法思想。在一个特定大小的字符串或数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度。
题目
算法思路
思路一
考虑滑动窗口,首先我们需要先定义的一个sum存放数组索引0-k的和
定义一个滑动窗口,在一个k的长度内,k向每向前移动一格,那么更新后的sum的值就为增加前一个位置(i),删除后一个位置的(i-k)。
初始时,最左侧的子数组下标为[0,k-1],当k<i<nums.length时,数组下标从[i-k,i-1]到[i-k+1,i]时,长度为k的新子数组中,nusm[i-k]移出,nums[i]移入。转化为代码为sum=sum-nums[i-k]+nums[i];
源码
class Solution {
public double findMaxAverage(int[] nums, int k) {
int sum=0;
//首先初始化sum为数组前k个
for(int i=0;i<k;i++){
sum+=nums[i];
}
int max=sum;
for(int j=k;j<nums.length;j++){
sum=sum-nums[j-k]+nums[j];
max=Math.max(sum,max);
}
return 1.0*max/k;
}
}
时间和空间复杂度
时间复杂度:O(n),其中 n 是数组的长度。
空间复杂度:O(1)
思路二(未解决)
滑动窗口首先要考虑的是滑动,我在思路二中没有理解滑动的意思,于是就使用的双指针,一个l,一个r=l+k,在用for以此来达到滑动的目的。
源码
class Solution {
public double findMaxAverage(int[] nums, int k) {
//定义长度为k的窗口
int left=0,right=left+k;
//max
double sum=0;
double max=0;
for(int i=left;i<right;i++){
//求当前窗口平均值
sum+=nums[i];
double tempmax=sum/k;
if(tempmax>max){
max=tempmax;
}
}
return max;
}
}
所用API
Math.math()求最大值
总结(滑动窗口应用场景)
-
需要输出或比较的结果在原数据结构中是连续排列的(字符串中的连续不重复子串,数组中的连续元素最大和)
-
每次窗口滑动时,只需观察窗口两端元素的变化,无论窗口多长,每次只操作两个头尾元素,当用到的窗口比较长时,可以显著减少操作次数
-
窗口内元素的整体性比较强,窗口滑动可以只通过操作头尾两个位置的变化实现,但对比结果时往往要用到窗口中所有元素(检查窗口中是否含有重复字符,对比窗口中元素的和)