题目:
给你一个由 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
🙇♂️ 感想: 题目是清晰易懂的。我自己也考虑到滑动窗口了,只是看了答案之后觉得我这个滑动窗口跟没有的一样就是,可能严格意义上说我的不叫滑动窗口。一开始我想的是每次计算滑动窗口中的和,与结果集进行比较,取最大值。这样的结果可想而知,时间复杂度太高了,直接超时。 然后我又想到一个优化方案就是, 每次滑动窗口其实就是第一个值离开,下一个值加进来,那么我可以比较第一个值与下一个值哪个大,如果下一个值小的话,直接跳过,知道找到下一个比第一个值大的值,可想而知也没有优化多少。后面我也会把我的代码贴出。下面解题思路我也会参考别人更优的方案给出
🙇♂️ 解题思路: 首先计算前k个数之和加入结果集中, 然后从第k个下标开始循环,从上一个滑动窗口的和中-nums[i - k] ,再+nums[i] 就可以得到当前窗口的和,然后与结果集比较,取最大值即可。
// 参考别人思路
function findMaxAverage(nums, k) {
let temp = nums.slice(0, k).reduce((pre, item) => pre + item)
let result = temp
for (let i = k; i < nums.length; i++) {
temp = temp - nums[i - k] + nums[i]
result = Math.max(result, temp)
}
return result / k
}
// 我最开始的想法
function findMaxAverage(nums, k) {
if (k === nums.length) return (nums.reduce((pre, count) => pre + count)) / k
let result = null
for (let i = 0; i <= nums.length - k; ) {
let temp = nums.slice(i, k+i).reduce((pre, item) => pre + item)
// console.log(i)
if (result === null) {
result = temp
} else {
result = Math.max(result, temp)
}
if (nums[k+i] <= nums[i]) {
while(nums[k+i] <= nums[i]) {
i++
}
continue
} else {
i++
}
}
return result / k
}