643. 子数组最大平均数 I (滑动窗口)

前言

滑动窗口是一种算法思想。在一个特定大小的字符串数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度。


题目

643. 子数组最大平均数 I
在这里插入图片描述


算法思路

思路一

在这里插入图片描述

考虑滑动窗口,首先我们需要先定义的一个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()求最大值


总结(滑动窗口应用场景)

  1. 需要输出或比较的结果在原数据结构中是连续排列的(字符串中的连续不重复子串,数组中的连续元素最大和)

  2. 每次窗口滑动时,只需观察窗口两端元素的变化,无论窗口多长,每次只操作两个头尾元素,当用到的窗口比较长时,可以显著减少操作次数

  3. 窗口内元素的整体性比较强,窗口滑动可以只通过操作头尾两个位置的变化实现,但对比结果时往往要用到窗口中所有元素(检查窗口中是否含有重复字符,对比窗口中元素的和)

参考文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心比较堵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值