Given an array consisting of n
integers, find the contiguous subarray of given length k
that has the maximum average value. And you need to output the maximum average value.
给定一个整数组成的数组,找到长度为k的连续子数组,它们的连续平均值是最大的,输出这个平均值。
Example 1:
Input: [1,12,-5,-6,50,3], k = 4
Output: 12.75
Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75
Note:
- 1 <=
k
<=n
<= 30,000. - Elements of the given array will be in the range [-10,000, 10,000].
Solutions:
Python
'''
这个是滑动窗口的方法,其解法的妙处在于滑动时窗口后三个数的和是不变的
永远更新窗口的第一个数和最后一个数,这样会明显减少计算量,比直接暴力
遍历的时间要少,如果直接从nums中遍历每一个窗口做加和,leetcode是超时的
'''
(1)
class Solution:
def findMaxAverage(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: float
"""
size = len(nums)
cursum = sum(nums[:k])
maxsum = cursum
for i in range(1,size-k+1):
cursum -= nums[i-1] #窗口进行了滑动,抛弃原窗口的第一个值
cursum += nums[i+k-1] #加上窗口滑动之后被纳入窗口的值,这两步会节约很多时间
if cursum >maxsum: #更新最大sum
maxsum = cursum
return maxsum/k
(2)
'''
这个方法也是用的滑动窗口,不过在代码上更华丽一些
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b) # 打包为元组的列表
zipped = [(1, 4), (2, 5), (3, 6)]
zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
'''
class Solution:
def findMaxAverage(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: float
"""
cursum = maxsum = sum(nums[:k])
for prev, nextt in zip(nums, nums[k:]): #prev为元组第一个元素,nextt为元组第二个元素
cursum += nextt - prev
if cursum > maxsum:
maxsum = cursum
return maxsum/k
C++
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
int size = nums.size();
int cursum = 0;
for (int i = 0;i<k;i++){
cursum += nums[i];
}
double maxsum = cursum; //注意这里是double类型,float类型的精度不够
for (int i=1;i<=size-k;i++){
cursum -= nums[i-1];
cursum += nums[i+k-1];
if(cursum>maxsum){
maxsum = cursum;
}
}
return maxsum/k;
}
};