滑动窗口算法

滑动窗口算法是一种解决数组或字符串中连续子数组或子字符串问题的有效技巧。该算法通过维护一个窗口,该窗口在数组或字符串上滑动,以找到符合特定条件的子数组或子字符串。

通常,滑动窗口算法可以用于解决以下类型的问题:

  1. 找到具有特定性质的子数组或子字符串,例如最小值、最大值、总和等。
  2. 查找包含给定元素的子数组或子字符串。
  3. 找到满足一定条件的最短子数组或子字符串。

滑动窗口算法的一般步骤如下:

  1. 初始化窗口的起始位置和大小。
  2. 将窗口的右边界向右移动,直到满足特定条件。
  3. 缩小窗口大小或移动左边界,以满足问题的要求。
  4. 重复步骤2和3,直到遍历完整个数组或字符串。

这种算法的关键在于如何有效地移动窗口,并在每个步骤中更新窗口内的状态,以在满足特定条件时找到所需的结果。这种算法通常具有较低的时间复杂度,因为在每个步骤中,只需要对窗口中的元素进行常数级别的操作。

举例来说,如果要解决一个找到数组中和大于等于某个特定值的最短子数组的问题,可以使用滑动窗口算法。在这种情况下,我们可以通过不断地增加窗口的右边界,并根据当前窗口内的和来移动左边界,以找到最短的满足条件的子数组。

下面举个例题:

Leetcode:无重复最长字串https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

假设我们选择字符串中的第 k 个字符作为起始位置,并且得到了不包含重复字符的最长子串的结束位置为 rk 。那么当我们选择第 k+1字符作为起始位置时,首先从 k+1到 rk的字符显然是不重复的,并且由于少了原本的第 k个字符,我们可以尝试继续增大 rk,直到右侧出现了重复字符为止。

这样一来,我们就可以使用「滑动窗口」来解决这个问题了:

  • 我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 rk
  • 在每一步的操作中,我们会将左指针向右移动一格,表示我们开始枚举下一个字符作为起始位置 ,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着以左指针开始 的,不包含重复字符的最长子串。我们记录下这个子串的长度;
  • 在枚举结束后,我们找到的最长的子串的长度即为答案
java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        //哈希集合,记录每个字符是否出现过
        Set<Character> occ = new HashSet<Character>();
        int n=s.length();
        //右指针,初始值为-1;相当于我们在字符串的左边界的左侧,还没有开始移动
        int rk=-1,ans=0;
        for (int i = 0; i < n; i++) {
            if(i!=0){
                //左指针向右移动一格,移除一个字符
                occ.remove(s.charAt(i-1));
            }

            while(rk + 1 < n && !occ.contains(s.charAt(rk + 1))){
                //不断向右移动指针
                occ.add(s.charAt(rk+1));
                ++rk;
            }

            //第i到rk个字符是一个极长的无重复字符字串
            ans = Math.max(ans, rk - i + 1);
        }
        return ans;
    }
}
相关推荐
地平线开发者2 分钟前
征程 6 工具链性能分析与优化 2|模型性能优化建议
算法·自动驾驶
Duck Bro4 分钟前
数据结构:顺序表(动态顺序表)
c语言·数据结构·c++·学习·算法
DK2215140 分钟前
机器学习系列-----主成分分析(PCA)
人工智能·算法·机器学习
oliveira-time1 小时前
爬虫学习8
开发语言·javascript·爬虫·python·算法
jinmo_C++1 小时前
数据结构——链表(带有头节点)
数据结构·链表
点云侠1 小时前
二维椭圆拟合算法及推导过程
开发语言·c++·算法·计算机视觉·matlab
一直学习永不止步2 小时前
LeetCode题练习与总结:迷你语法分析器--385
java·数据结构·算法·leetcode·字符串··深度优先搜索
Dragonlongbo2 小时前
leetcode01 --- 环形链表判定
算法·leetcode·职场和发展
-cc- Lynn2 小时前
链表类算法【leetcode】
算法·leetcode·链表
顾京2 小时前
基于扩散模型的表单插补
人工智能·深度学习·算法