其他系列文章导航
文章目录
[2.1 滑动窗口含义](#2.1 滑动窗口含义)
[2.2 滑动窗口一般解法](#2.2 滑动窗口一般解法)
[2.3 方法一:滑动窗口](#2.3 方法一:滑动窗口)
[3.1 方法一:滑动窗口](#3.1 方法一:滑动窗口)
[4.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 滑动窗口一般解法
滑动窗口算法是一种常见的算法技巧,用于解决一些数组或字符串相关的问题。下面将详细介绍滑动窗口算法的工作原理和应用场景:
工作原理:
- 窗口大小:滑动窗口算法通过设定一个窗口的大小来解决问题。窗口通常是一个连续的子数组或子字符串。
- 初始化窗口:初始化窗口的起始位置,并根据问题需求设定窗口的大小。
- 移动窗口:通过移动窗口的起始位置,不断调整窗口的大小和位置,以找到满足问题条件的解。
- 更新解:根据窗口的移动和调整,更新问题的解,并记录或返回所需的结果。
应用场景:
- 最小/最大子数组/子字符串:寻找给定数组或字符串中满足特定条件的最小或最大的子数组或子字符串。
- 字符串匹配:在一个字符串中寻找另一个字符串的出现或满足特定条件的子串。
- 滑动窗口和哈希表结合:通过使用哈希表来优化滑动窗口算法,提高效率。
- 优化窗口大小:根据问题的特性,调整窗口大小以寻找最佳解。
滑动窗口算法的步骤通常如下:
- 初始化窗口的起始位置和结束位置,使其满足问题的要求。
- 进入循环,不断移动窗口的起始位置和结束位置,直到窗口滑动到数组或字符串的末尾。
- 在每一次循环中,检查窗口内的元素是否满足问题的要求。如果满足条件,则更新解或执行其他操作。如果不满足条件,则继续移动窗口。
- 在移动窗口时,要更新窗口内的元素和相应的数据结构,以确保窗口的正确性。
- 重复步骤2到步骤4,直到遍历完整个数组或字符串,返回解或所需的结果。
需要注意的是,滑动窗口算法的时间复杂度取决于窗口的大小和问题的特性。在某些情况下,可能需要通过调整窗口大小来优化算法的性能。
2.3 方法一:滑动窗口
思路与算法:
滑动窗口顾名思义先要有窗口。
首先定义两个变量 sum 和 maxSum ,sum 存每次 k 个元素和, maxSum 存最大的 sum 。
那我们就在数组最前方取 k 个元素当作窗口,计算出 sum 。
然后更新 maxSum 。
窗口如何滑动? 去掉最前面的元素,加上后一个元素,实现滑动。
时刻更新 maxSum ,最后返回 (double) maxSum/k 。
三、代码
3.1 方法一:滑动窗口
Java版本:
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++版本:
cpp
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版本:
python
class Solution:
def findMaxAverage(self, nums: List[int], k: int) -> float:
_sum = sum(nums[:k])
max_sum = _sum
for 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)。