【最大滑动窗口】水果成篮(python纯数组版)

文章介绍了如何使用最大滑动窗口算法解决农场摘果问题,通过维护两个篮子中水果的种类,找到满足最多不同种类水果的滑动窗口,以获取最大的水果收集数量。

目录

一、原题目描述

二、题目解答


一、原题目描述

题目:你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

  • 你只有两个篮子,并且每个篮子只能装单一类型的水果。每个篮子能够装的水果总量没有限制。
  • 你可以选择任意一棵树开始采摘,你必须从每棵树(包括开始采摘的树)上恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
  • 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

举例

[1,2,1]——max_num=3

[0,1,2,2]——max_num=3  采摘 [1,2,2] 这三棵树,如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。

[1,2,3,2,2]——max_num=4 采摘 [2,3,2,2] 这四棵树,如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。

[3,3,3,

<think>嗯,用户想了解滑动窗口算法及其二维本的实现和应用场景。首先,我需要回忆一下滑动窗口的基本概念,然后扩展到二维的情况。根据之前的引用资料,滑动窗口通常用于处理数组或字符串中的子区间问题,比如查找满足某些条件的最长子串或最短覆盖子串。例如,引用[4]中的水果篮子问题,用哈希表维护窗口内的水果类型,当类型超过两种时调整窗口左边界,这很典型。接下来是二维滑动窗口。用户可能想知道如何将一维窗口扩展到矩阵或二维数组中。比如,在图像处理中,滑动窗口可以用来进行局部特征提取,或者在矩阵中寻找满足条件的子矩阵。引用[2]提到了最小矩阵宽度的问题,使用左右指针在矩阵列上滑动,这可能涉及到二维窗口的处理,但具体实现可能需要更详细的解释。 关于实现,一维的滑动窗口通常用双指针(start和end)来维护窗口的边界,根据条件移动指针。例如,引用[3]中的代码示例,用左右指针l和r来枚举右端点,调整左端点以保持窗口的有效性。二维的情况可能需要嵌套循环,或者在两个维度上分别使用滑动窗口,比如行和列都进行滑动,或者使用固定大小的窗口遍历整个矩阵。应用场景方面,一维滑动窗口常用于字符串处理(如最长无重复子串)、数组问题(如子数组和)。二维的可能用于图像处理、矩阵中的子矩阵问题,比如最大子矩阵和,或者查找特定模式的子区域。引用[2]提到的“最小矩阵宽度”可能是一个应用,但需要更具体的例子。现在需要确保回答结构清晰,分点讲解。首先介绍滑动窗口算法,包括原理、实现步骤、代码示例和应用场景。然后讨论二维扩展,说明实现的不同之处,可能的代码结构,以及应用示例。同时,根据用户提供的引用,适当引用相关部分,比如引用[4]中的Java代码,引用[3]中的C++示例,引用[2]中的矩阵处理思路。 需要注意用户的引用中,引用[3]提到了排序区间后使用滑动窗口计算毛毯覆盖的最大瓷砖数,这可能是一个二维问题的变种,但代码本身还是一维的处理。而引用[2]中的最小矩阵宽度可能更接近二维,但具体步骤描述可能不够详细,需要推测如何实现二维窗口。 在生成相关问题的时候,可以围绕滑动窗口的基本原理、优化方法、二维实现难点、具体应用案例等提问,帮助用户深入理解。最后,确保使用正确的中文表达,数学公式用$$...$$格式,代码块用正确语法,引用标识自然添加。</think>### 滑动窗口算法详解 #### 一、一维滑动窗口算法 **原理**:通过维护动态窗口的左右边界(双指针),在满足条件时扩展右边界,不满足时收缩左边界,高效解决子区间问题。 **核心公式**: $$ \text{窗口长度} = \text{右指针位置} - \text{左指针位置} + 1 $$ **实现步骤**: 1. 初始化左右指针`left=0`, `right=0` 2. 移动右指针,扩展窗口 3. 当窗口不满足条件时,移动左指针收缩窗口 4. 记录最优解 **代码示例(查找最长无重复子串)**: ```python def lengthOfLongestSubstring(s: str) -> int: char_map = {} max_len = 0 left = 0 for right in range(len(s)): if s[right] in char_map: left = max(left, char_map[s[right]] + 1) char_map[s[right]] = right max_len = max(max_len, right - left + 1) return max_len ``` **应用场景**: - 字符串:最长无重复子串(如上述代码)[^4] - 数组:子数组和满足条件的最小长度(如$target=7$时,数组$[2,3,1,2,4,3]$的最短子数组为$[4,3]$) - 数据流分析:实时统计窗口内最大值(如股票价格波动分析) --- #### 二、二维滑动窗口算法 **原理**:在矩阵中扩展窗口维度,通常结合行方向滑动和列方向累积数据,或使用固定大小的窗口遍历矩阵。 **核心公式**(固定大小窗口): $$ \text{子矩阵和} = \sum_{i=x}^{x+h}\sum_{j=y}^{y+w} matrix[i][j] $$ **实现步骤**: 1. **行方向预处理**:计算每行的前缀和 2. **列方向滑动**:对每一列范围,通过累积行数据计算子矩阵和 3. **动态调整窗口**:根据条件调整窗口大小或位置 **代码示例(矩阵中最大子矩阵和)**: ```python def maxSubMatrix(matrix): rows = len(matrix) cols = len(matrix[0]) max_sum = -float('inf') # 遍历所有可能的行组合 for top in range(rows): row_sum = [0] * cols for bottom in range(top, rows): # 累积当前行的值 for c in range(cols): row_sum[c] += matrix[bottom][c] # 在一维数组上应用滑动窗口 current_max = kadane(row_sum) max_sum = max(max_sum, current_max) return max_sum def kadane(arr): max_current = max_global = arr[0] for num in arr[1:]: max_current = max(num, max_current + num) max_global = max(max_global, max_current) return max_global ``` **应用场景**: - 图像处理:局部特征提取(如边缘检测) - 矩阵分析:最大子矩阵和(如上述代码)[^2] - 数据压缩:固定窗口内的数据编码(如JPEG分块) --- #### 三、关键对比 | 维度 | 时间复杂度 | 典型问题 | 实现复杂度 | |--------|------------------|------------------------------|------------| | 一维 | $O(n)$ | 最长无重复子串 | 低 | | 二维 | $O(mn^2)$ | 最大子矩阵和 | 高 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值