leetcode643. 子数组最大平均数 I
一、题目描述
给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。
请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。
任何误差小于 10-5 的答案都将被视为正确答案。
示例 1:
输入:nums = [1,12,-5,-6,50,3], k = 4
输出:12.75
解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75
示例 2:
输入:nums = [5], k = 1
输出:5.00000
提示:
n == nums.length
1 <= k <= n <= 105
-104 <= nums[i] <= 104
二、题目解析
1、暴力,双重for循环
class Solution {public double findMaxAverage(int[] nums, int k) {if(nums == null || nums.length < k){return 0;}double sum = 0,max = Integer.MIN_VALUE;int count = 0;for(int i = 0;i <= nums.length - k;i++){sum = nums[i];count = 1;for(int temp = i + 1;count < k && temp < nums.length;count++,temp++){sum += nums[temp];}max = sum > max ? sum : max;}return max / k;}
}
时间复杂度O((n-k+1)*k),空间复杂度O(1)
运行超时
2、滑动窗口
思考在1基础上,内层for循环可以优化,第一次拿到前4个元素,形成初始窗口,后面向右滑动即可,每次右入1个元素,左出1个元素;在滑动的过程中不断更新最大值。
class Solution {public double findMaxAverage(int[] nums, int k) {if(nums == null || nums.length < k){return 0;}double sum = 0,max = Integer.MIN_VALUE;int count = 0;//i指的是右边界的可能位置,故最大值是nums.length - 1for(int i = 0;i < nums.length;i++){//右边新的元素进入窗口sum += nums[i];//初始化窗口时,窗口大小不足k则扩充if(i < k - 1){continue;}//更新最大值max = sum > max ? sum : max;//最左边元素离开窗口sum -= nums[i - k + 1];}return max / k;}
}
时间复杂度O(n),空间复杂度O(1)