【数据结构和算法】子数组最大平均数 I

2023-12-21 12:12

本文主要是介绍【数据结构和算法】子数组最大平均数 I,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其他系列文章导航

Java基础合集
数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、题目描述

二、题解

2.1 滑动窗口含义

2.2 滑动窗口一般解法

2.3 方法一:滑动窗口

三、代码

3.1 方法一:滑动窗口

四、复杂度分析

4.1 方法一:滑动窗口
 


前言

这是力扣的 643 题,难度简单,解题方案有很多种,本文讲解我认为最奇妙的一种。


一、题目描述

原题链接:力扣 643 题 子数组最大平均数 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

二、题解

这道题目不难,但是确实是一道非常经典的滑动窗口问题,它可以帮助我们很好地理解滑动窗口算法的本质和应用。

2.1 滑动窗口含义

滑动窗口算法是一种在数组或列表中寻找特定元素的强大工具,可以高效地解决一系列问题。

例如找到一个数组中最大的K个元素、在一个数组中查找子数组的数量等等。

滑动窗口算法的核心思想是在数组或列表中保持一个连续的、大小固定的窗口,并在遍历过程中动态地调整窗口的位置。

2.2 滑动窗口一般解法

滑动窗口算法是一种常见的算法技巧,用于解决一些数组或字符串相关的问题。下面将详细介绍滑动窗口算法的工作原理和应用场景:

工作原理:

  1. 窗口大小:滑动窗口算法通过设定一个窗口的大小来解决问题。窗口通常是一个连续的子数组或子字符串。
  2. 初始化窗口:初始化窗口的起始位置,并根据问题需求设定窗口的大小。
  3. 移动窗口:通过移动窗口的起始位置,不断调整窗口的大小和位置,以找到满足问题条件的解。
  4. 更新解:根据窗口的移动和调整,更新问题的解,并记录或返回所需的结果。

应用场景:

  1. 最小/最大子数组/子字符串:寻找给定数组或字符串中满足特定条件的最小或最大的子数组或子字符串。
  2. 字符串匹配:在一个字符串中寻找另一个字符串的出现或满足特定条件的子串。
  3. 滑动窗口和哈希表结合:通过使用哈希表来优化滑动窗口算法,提高效率。
  4. 优化窗口大小:根据问题的特性,调整窗口大小以寻找最佳解。

滑动窗口算法的步骤通常如下:

  1. 初始化窗口的起始位置和结束位置,使其满足问题的要求。
  2. 进入循环,不断移动窗口的起始位置和结束位置,直到窗口滑动到数组或字符串的末尾。
  3. 在每一次循环中,检查窗口内的元素是否满足问题的要求。如果满足条件,则更新解或执行其他操作。如果不满足条件,则继续移动窗口。
  4. 在移动窗口时,要更新窗口内的元素和相应的数据结构,以确保窗口的正确性。
  5. 重复步骤2到步骤4,直到遍历完整个数组或字符串,返回解或所需的结果。

需要注意的是,滑动窗口算法的时间复杂度取决于窗口的大小和问题的特性。在某些情况下,可能需要通过调整窗口大小来优化算法的性能。

2.3 方法一:滑动窗口

思路与算法:

滑动窗口顾名思义先要有窗口。

首先定义两个变量 sum 和 maxSum ,sum 存每次 k 个元素和, maxSum 存最大的 sum 。

那我们就在数组最前方取 k 个元素当作窗口,计算出 sum 。

然后更新 maxSum 。

窗口如何滑动? 去掉最前面的元素,加上后一个元素,实现滑动。

 时刻更新 maxSum ,最后返回 (double) maxSum/k 。


三、代码

3.1 方法一:滑动窗口

Java版本:

class Solution {public double findMaxAverage(int[] nums, int k) {int sum = 0, maxSum;for (int i = 0; i < k; i++) {sum += nums[i];}maxSum = sum;for (int i = k; i < nums.length; i++) {sum = sum - nums[i - k] + nums[i];maxSum=Math.max(maxSum,sum);}return (double) maxSum/k;}
}

C++版本:

class Solution {
public:double findMaxAverage(vector<int>& nums, int k) {int sum = 0, maxSum;for (int i = 0; i < k; i++) {sum += nums[i];}maxSum = sum;for (int i = k; i < nums.size(); i++) {sum = sum - nums[i - k] + nums[i];maxSum = max(maxSum, sum);}return static_cast<double>(maxSum) / k;}
};

Python版本:

class Solution:def findMaxAverage(self, nums: List[int], k: int) -> float:_sum = sum(nums[:k])max_sum = _sumfor i in range(k, len(nums)):_sum = _sum - nums[i - k] + nums[i]max_sum = max(max_sum, _sum)return max_sum / k

四、复杂度分析

4.1 方法一:滑动窗口

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。遍历数组一次。
  • 空间复杂度:O(1)。

这篇关于【数据结构和算法】子数组最大平均数 I的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519961

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::