文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

滑动窗口算法

2023-09-06 08:38

关注

目录

滑动窗口算法

基本思想

 可解决问题

应用

题目一:最小覆盖子串

题目解读:

 代码

题目二:长度最小的子数组

题目解读

代码

滑动算法窗口的优缺点

优点:

缺点:


滑动窗口算法

首先介绍一下什么是滑动窗口:滑动窗口算法是一种在数组或字符串中寻找特定模式的算法,它可以在 O(n) 的时间复杂度内解决一些字符串或数组相关的问题。

基本思想

滑动窗口算法的基本思想是维护一个窗口,窗口内是需要处理的数据,每次移动窗口时,我们只需要计算新窗口与旧窗口的区别即可,这样可以大大减少计算量。

具体地说,滑动窗口算法通常包括以下几个步骤:

  1. 初始化左右指针,表示窗口的左右边界。

  2. 移动右指针,扩大窗口,直到找到符合条件的窗口。

  3. 移动左指针,缩小窗口大小,直到不能再缩小为止。

  4. 在窗口移动的过程中,记录窗口的状态,例如最大值、最小值、子串长度等等。

  5. 返回窗口记录的结果。

 可解决问题

滑动窗口算法可以用于解决一些数组和字符串相关的问题,例如:

找到最长的连续子数组或子字符串:可以使用滑动窗口算法来寻找最长的连续子数组或子字符串。在遍历数组或字符串时,我们可以维护一个窗口,通过移动窗口来寻找最长的连续子数组或子字符串。

找到满足某些条件的子数组或子字符串:可以使用滑动窗口算法来寻找满足某些条件的子数组或子字符串。在遍历数组或字符串时,我们可以维护一个窗口,通过移动窗口来寻找满足某些条件的子数组或子字符串。

找到最小的覆盖子串:可以使用滑动窗口算法来寻找最小的覆盖子串。在遍历字符串时,我们可以维护一个窗口,通过移动窗口来寻找最小的覆盖子串。

找到无重复字符的最长子串:可以使用滑动窗口算法来寻找无重复字符的最长子串。在遍历字符串时,我们可以维护一个窗口,通过移动窗口来寻找无重复字符的最长子串。

滑动窗口算法通常适用于处理数组和字符串问题,而且要求问题可以通过窗口内的元素来计算得出。此外,滑动窗口算法通常可以将时间复杂度优化到线性,因此在处理大规模数据时具有很好的效率。

应用

下面,我将通过两道简单题目来演示滑动窗口算法的应用。

题目一:最小覆盖子串

给定两个字符串 S 和 T,求 S 中包含 T 所有字符的最短子串。

示例:

输入:S = "ADOBECODEBANC",   T = "ABC"

输出:"BANC"

题目解读:

我们可以维护两个指针 left 和 right,表示当前窗口的左右边界。初始时,左指针和右指针都指向字符串 S 的第一个字符。我们先移动右指针,直到找到包含字符串 T 的所有字符的子串。然后,我们移动左指针,缩小窗口大小,直到不能再缩小为止。在这个过程中,我们记录窗口的最小长度,并记录最小子串的起始位置。最后返回最小子串。

 代码

public String minWindow(String s, String t) {    int[] hash = new int[256];//ASCII 字符集共包含256个字符,因此使用长度为256的数组来记录窗口中每个字符出现的次数。    for (char c : t.toCharArray()) {        hash[c]++;    }    int left = 0, right = 0, count = t.length(), start = 0, len = Integer.MAX_VALUE;    while (right < s.length()) {        if (hash[s.charAt(right)] > 0) {            count--;        }        hash[s.charAt(right)]--;        right++;        while (count == 0) {            if (right - left < len) {                len = right - left;                start = left;            }            if (hash[s.charAt(left)] == 0) {                count++;            }            hash[s.charAt(left)]++;            left++;        }    }    return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);}

题目二:长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target,找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

输入:nums = [2,3,1,2,4,3], target = 7

输出:2

题目解读

我们可以维护两个指针 left 和 right,表示当前窗口的左右边界。初始时,左指针和右指针都指向数组的第一个元素。我们先移动右指针,直到窗口内的元素之和大于等于 target。然后,我们移动左指针,缩小窗口大小,直到不能再缩小为止。在这个过程中,我们记录窗口的最小长度,并更新最小长度的值。最后,返回最小长度。

代码

public int minSubArrayLen(int target, int[] nums) {    int left = 0, right = 0, sum = 0, len = Integer.MAX_VALUE;    while (right < nums.length) {        sum += nums[right];        while (sum >= target) {            len = Math.min(len, right - left + 1);            sum -= nums[left];            left++;        }        right++;    }    return len == Integer.MAX_VALUE ? 0 : len;}

滑动算法窗口的优缺点

优点:

  1. 时间复杂度较低:滑动窗口算法的时间复杂度通常是O(n),因为它只需要遍历一次原数组。
  2. 空间复杂度较低:滑动窗口算法通常只需要使用常数级别的额外空间。
  3. 简单易懂:滑动窗口算法的思路比较简单,容易理解和实现。

缺点:

  1. 无法解决所有子串问题:滑动窗口算法只适用于解决一些特定类型的子串问题,无法解决所有子串问题。
  2. 可能存在重复计算:在一些情况下,滑动窗口算法可能会对同一段区间进行重复计算,导致效率降低。
  3. 可能存在局限性:滑动窗口算法有些场景下可能无法得到最优解,需要结合其他算法进行优化。

来源地址:https://blog.csdn.net/m0_63951142/article/details/130671127

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯