【算法】滑动窗口

一、概念

  • 滑动窗口是一种算法思想,主要用于解决数组或字符串的问题。它通过维护一个窗口,在数组或字符串上移动,以寻找满足特定条件的子数组或子字符串。

二、基本思想:

  • 使用两个指针left和right来表示窗口的边界。初始情况下,left和right都指向窗口的起始位置。然后,不断移动right指针以扩大窗口,直到满足特定条件。接着,移动left指针以缩小窗口,直到不满足特定条件。然后再次移动right指针,不断循环这个过程,直到遍历完整个数组或字符串。

三、算法框架

滑动窗口算法的框架如下:

  1. 初始化窗口的左边界left和右边界right,并且将窗口内的数据初始化为一个合法的初始值。
  2. 开始移动右边界right,不断扩大窗口,直到满足特定条件为止。
  3. 当窗口满足特定条件时,记录结果(如更新最长子串的长度等)。
  4. 开始移动左边界left,缩小窗口,直到不满足特定条件停止。
  5. 重复步骤2到4,直到遍历完整个数组或字符串。

具体来说,可以按照以下步骤来实现滑动窗口算法:

  1. 初始化left和right指针,以及其他需要的辅助变量或数据结构。
  2. 使用一个循环来移动right指针,直到满足特定条件。在每次移动right指针时,根据需要更新窗口内的数据、记录结果等。
  3. 在循环内部判断窗口是否满足特定条件,如果满足,则记录结果。
  4. 在循环内部使用另一个循环来移动left指针,缩小窗口,直到不满足特定条件。
  5. 在循环结束后,返回结果。

滑动窗口算法的时间复杂度通常为O(n),其中n为数组或字符串的长度。

四、算法简单示例

找到数组中的最大子数组和,数组为nums,子数组长度K:

public static int maxSubarraySum(int[] nums, int k) {
   
   
    // 初始化窗口的左边界和右边界
    int left = 0;
    int right = 0;

    // 初始化当前窗口内的和以及最大子数组和
    int currentSum = 0;
    int maxSum = Integer.MIN_VALUE;

    // 开始移动右边界,扩大窗口
    while (right < nums.length) {
   
   
        // 更新当前窗口内的和
        currentSum += nums[right];

        // 当窗口大小大于 k 时,开始移动左边界,缩小窗
### 滑动窗口算法实现与应用场景 滑动窗口算法是一种高效解决子数组或子字符串问题的技术,主要通过两个指针(通常称为 `left` 和 `right`)动态调整窗口大小来优化计算效率[^1]。 #### 1. 基本原理 滑动窗口的核心在于避免冗余计算。通过对窗口边界的灵活控制,在遍历过程中逐步缩小解空间并实时更新最优解。具体来说,该方法适用于那些具有某种单调性质的问题场景,比如寻找符合条件的最长/最短子数组等问题[^2]。 #### 2. 实现步骤 以下是滑动窗口算法的一般实现流程: - **初始化窗口边界**:设置初始状态下的左边界 (`left`) 和右边界 (`right`)。 - **扩展窗口**:不断向右移动 `right` 边界以扩大窗口范围,直至满足特定条件为止[^3]。 - **收缩窗口**:一旦发现当前窗口已超出需求约束,则尝试从左侧缩减窗口尺寸(即增加 `left` 的位置),以便探索更优可能性。 - **记录最佳结果**:在整个迭代期间持续跟踪所遇到的最佳解决方案,并最终返回之。 下面给出一段基于 Python 的简单例子用于说明如何查找给定列表中总和至少达到某个阈值 k 的最小长度连续子集: ```python def minSubArrayLen(s, nums): n = len(nums) res = float('inf') sum_val = 0 l = 0 for r in range(n): sum_val += nums[r] while sum_val >= s: res = min(res, r - l + 1) sum_val -= nums[l] l += 1 return 0 if res == float('inf') else res ``` 此函数接受参数 `s`(目标数值) 及 数组 `nums`, 并运用双指针技巧定位到满足累加超过等于`s`的第一个区间起点结束坐标差作为候选答案之一; 同时保持全局变量res始终存储目前观察过的所有可能区间的最小宽度. 另外还有一种情况涉及到字符频率统计的任务也可以采用类似的思维模式去完成.[^4] #### 应用实例分析 考虑这样一个实际的例子——在一个由正整数构成的大规模数据集中快速找出任意两数相加之和恰好匹配指定常量X的所有组合对儿数目。如果单纯依靠双重循环枚举每一对元素的话显然会面临性能瓶颈(O(N²))级别的时间消耗。然而借助于滑窗技术却可以显著降低整体开销至线性扫描程度O(N): 首先按照升序排列原始资料列; 接着定义左右两端游标分别指向首尾项; 最后依据两者合计关系决定下一步动作方向(若不足则推进右侧索引否则回撤前者), 直至上限被完全超越停止整个进程. 这种方法不仅逻辑清晰而且执行速度快很多倍! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值