作者: 负雪明烛
id: fuxuemingzhu
公众号:每日算法题


题目地址:https://leetcode.com/problems/maximum-average-subarray-i/description/

题目描述

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.

  1. Example 1:
  2. Input: [1,12,-5,-6,50,3], k = 4
  3. Output: 12.75
  4. Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75

Note:

  1. 1 <= k <= n <= 30,000.
  2. Elements of the given array will be in the range [-10,000, 10,000].

题目大意

求给定数组中长度为k的切片的最大平均值。

解题方法

首先需要区分两个概念:**子串(子数组)子序列。**这两个名词经常在题目中出现,非常有必要加以区分。子串sub-string(子数组 sub-array)是连续的,而子序列 subsequence 可以不连续。

方法一:preSum

今天题目让求最大平均数,由于 k 是不变的,因此可以先求区间的最大和,然后再除以 k。

上周我在题解中已经说过,求区间的和可以用 preSum。preSum 方法还能快速计算指定区间段 i ~ j 的元素之和。它的计算方法是从左向右遍历数组,当遍历到数组的 i 位置时,preSum表示 i 位置左边的元素之和。

假设数组长度为 N,我们定义一个长度为 N+1 的 preSum 数组,preSum[i] 表示该元素左边所有元素之和(不包含当前元素)。然后遍历一次数组,累加区间 [0, i) 范围内的元素,可以得到 preSum 数组。代码如下:

  1. N = len(nums)
  2. preSum = range(N + 1)
  3. for i in range(N):
  4. preSum[i + 1] = preSum[i] + nums[i]
  5. print(preSum)

利用 preSum 数组,可以在 O(1) 的时间内快速求出 nums 任意区间 [i, j] (两端都包含) 的各元素之和。

sum(i, j) = preSum[i + 1] - preSum[j]

对于本题,可以先遍历一次,求数组每个位置的 preSum,然后再遍历一次,求长度为 k 的每个区间的最大和。最终除以 k 得到最大平均数。

使用 Python2 写的代码如下。

  1. class Solution(object):
  2. def findMaxAverage(self, nums, k):
  3. """
  4. :type nums: List[int]
  5. :type k: int
  6. :rtype: float
  7. """
  8. N = len(nums)
  9. preSum = range(N + 1)
  10. for i in range(N):
  11. preSum[i + 1] = preSum[i] + nums[i]
  12. largest = float("-inf")
  13. for i in range(k - 1, N):
  14. largest = max(preSum[i + 1] - preSum[i + 1 - k], res)
  15. return largest / float(k)

方法二:滑动窗口

题目也可以抽象成长度固定为 k 的滑动窗口。当每次窗口右移的时候,需要把右边的新位置加到窗口中的中,把左边被移除的位置从窗口的减掉。这样窗口里面所有元素的是准确的,我们求出最大的和,最终除以 k 得到最大平均数。

这个方法只用遍历一次数组。

需要注意的是,需要根据 i 的位置,计算滑动窗口是否开始、是否要移除最左边元素:

  • i >= k - 1 时,最左边第一个滑动窗口内的元素刚好 k 个,开始计算滑动窗口的最大和。

  • i >= k 时,为了固定窗口的元素是 k 个,每次移动时需要将 i - k 位置的元素移除。

使用 Python2 写的代码如下。

  1. class Solution(object):
  2. def findMaxAverage(self, nums, k):
  3. """
  4. :type nums: List[int]
  5. :type k: int
  6. :rtype: float
  7. """
  8. sums = 0
  9. largest = float('-inf')
  10. for i, num in enumerate(nums):
  11. sums += num
  12. if i >= k:
  13. sums -= nums[i - k]
  14. if i >= k - 1:
  15. largest = max(sums, largest)
  16. return largest / float(k)

刷题心得

今天的题目非常好,虽然是个 Easy 题目,但是让我们练习了 preSum滑动窗口 两种方法的最基本用法。

  • preSum 方法要注意定义的 preSum 是否包含当前元素;
  • 滑动窗口 方法要注意窗口的大小要固定为 k。

日期

2018 年 2 月 3 日
2018 年 11 月 23 日 —— 这就星期五了??
2021 年 2 月 4 日 —— 快要过年了!

【LeetCode】643. 子数组最大平均数 I Maximum Average Subarray I (Python)的更多相关文章

  1. LeetCode 643. 子数组最大平均数 I(Maximum Average Subarray I)

    643. 子数组最大平均数 I 643. Maximum Average Subarray I 题目描述 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. LeetCo ...

  2. [Swift]LeetCode643. 子数组最大平均数 I | Maximum Average Subarray I

    Given an array consisting of n integers, find the contiguous subarray of given length k that has the ...

  3. Java实现 LeetCode 643 子数组最大平均数 I(滑动窗口)

    643. 子数组最大平均数 I 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例 1: 输入: [1,12,-5,-6,50,3], k = 4 输出: 12.7 ...

  4. Leetcode 643.子数组最大平均数I

    子数组最大平均数I 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例 1: 输入: [1,12,-5,-6,50,3], k = 4 输出: 12.75 解释: ...

  5. 力扣643.子数组最大平均数I-C语言实现

    题目 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例: 输入:[1,12,-5,-6,50,3], k = 4 输出:12.75 解释:最大平均数 (12-5- ...

  6. [LeetCode] Maximum Average Subarray II 子数组的最大平均值之二

    Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...

  7. [LeetCode] 644. Maximum Average Subarray II 子数组的最大平均值之二

    Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...

  8. 【Leetcode_easy】643. Maximum Average Subarray I

    problem 643. Maximum Average Subarray I 题意:一定长度的子数组的最大平均值. solution1:计算子数组之后的常用方法是建立累加数组,然后再计算任意一定长度 ...

  9. 643. Maximum Average Subarray I 最大子数组的平均值

    [抄题]: Given an array consisting of n integers, find the contiguous subarray of given length k that h ...

随机推荐

  1. Linux软件安装管理:rpm与yum

    目录 1. rpm包的管理 1.1 介绍 1.2 rpm包的简单查询指令 1.3 rpm 包名的基本格式 1.4 rpm其它指令 1.5 卸载rpm包 1.6 安装rpm包 2. yum 2.1 说明 ...

  2. 42-Remove Nth Node From End of List

    Remove Nth Node From End of List My Submissions QuestionEditorial Solution Total Accepted: 106592 To ...

  3. Oracle-with c as (select ......) 实现多次调用子查询结果

    with c as  (select a.trandt,sum(a.tranam) tranam from tran a group by a.trandt )   #将子查询抽取出来,以后可以直接重 ...

  4. day05 连表查询与子查询

    day05 连表查询与子查询 昨日内容回顾 表关系之一对一 换位思考之后得出两边都是不可以 要么是没有关系,要么是一对一 一对一的表关系外键虽然建在哪个都可以,但是建议建在查询频率多的表上 # 外键其 ...

  5. day14函数递归调用

    day14函数递归调用 1.装饰器叠加 def deco1(func1): def wrapper1(*args,**kwargs): print('=====>wrapper1 ') res1 ...

  6. Spark中的分区方法详解

    转自:https://blog.csdn.net/dmy1115143060/article/details/82620715 一.Spark数据分区方式简要 在Spark中,RDD(Resilien ...

  7. h5移动端设备像素比dpr介绍

    首先介绍一下概念 devicePixelRatio其实指的是window.devicePixelRatio window.devicePixelRatio是设备上物理像素和设备独立像素(device- ...

  8. js正则表达式之密码强度验证

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Linux学习 - 使用qq邮箱发送邮件

    1 打开qq邮箱,设置->账户->POP3/SMTP,开启服务 2 配置/etc/mail.rc文件 set from=73***32@qq.com #设置发送方邮件地址 set smtp ...

  10. redis入门到精通系列(三):key的通用操作和redis内部db的通用操作

    五种数据类型都用到了key,key本身是一种字符串,通过key可以获取redis中保存的对象.这一篇博客就将介绍key的通用操作. (一)key基本操作 删除key del key key是否存在 e ...