滑动窗口策略

对应力扣第3题:右指针前移,左指针也动态移动

1. 滑动窗口的 3 个 "核心装备"

实现滑动窗口只需要 3 个关键变量,作用单一,记清楚就行:

  • 左指针left :窗口的左边界,初始值0(从字符串开头开始),控制窗口收缩;
  • 哈希集合set :记录当前窗口内的所有字符,利用集合 "元素唯一" 的特性,快速判断新字符是否重复;
  • 最大长度maxLen :记录遍历过程中,无重复字符窗口的最大宽度,初始值0
2. 滑动窗口的 "核心规则"(唯一需要记的)

右指针right遍历字符串的每个字符(从0s.length-1),每一步只做 3 件事,循环执行直到遍历结束:

  1. 判断重复 :如果当前字符s[right]在集合中 (窗口内有重复),就把左指针指向的字符 从集合中删除,然后左指针left++(窗口左边界收缩),直到集合中没有s[right]
  2. 加入集合 :把当前字符s[right]加入集合(窗口右边界扩张,包含新字符);
  3. 更新最大长度 :计算当前窗口的宽度right - left + 1),如果比maxLen大,就更新maxLen
javascript 复制代码
/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
    let left = 0
    let maxLen = 0
    const set = new Set()
    const n = s.length
    for (let right = 0; right < n; right++) {
        while (set.has(s[right])) {
            set.delete(s[left])
            left++
        }
        set.add(s[right])
        maxLen = Math.max(maxLen, right - left + 1)
    }
    return maxLen
};

力扣438题

这个题目也是滑动窗口,但是窗口是固定大小的(等于p.length)

思路是开两个数组存26个字母各自在窗口中出现的次数,如果两个数组相等,那就是当前窗口是p的异位词。然后把开头的下标记录下来,窗口右移一个单位,同时左指针指的字母个数-1,右指针指到的+1

javascript 复制代码
/**
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
var findAnagrams = function (s, p) {
    const result = []
    const sLen = s.length
    const pLen = p.length
    const aCode = 'a'.charCodeAt(0)
    const pCount = new Array(26).fill(0)
    const sCount = new Array(26).fill(0)
    if (sLen < pLen) return result
    for (const c of p) {
        pCount[c.charCodeAt(0) - aCode]++
    }
    for (let i = 0; i < pLen; i++) {
        sCount[s[i].charCodeAt(0) - aCode]++
    }
    if (arrEqual(pCount, sCount)) {
        result.push(0)
    }
    for (let start = 1; start <= sLen - pLen; start++) {
        const leftChar = s[start - 1]
        sCount[leftChar.charCodeAt(0) - aCode]--
        const rightChar = s[start + pLen - 1]
        sCount[rightChar.charCodeAt(0)-aCode]++
        if (arrEqual(pCount, sCount)) {
            result.push(start)
        }
    }

    function arrEqual(arr1, arr2) {
        for (let i = 0; i < 26; i++) {
            if (arr1[i] !== arr2[i]) return false
        }
        return true
    }
    return result
};
相关推荐
leisoo80972 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
luj_17684 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
郝学胜-神的一滴5 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆5 小时前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill
Water_Sunzhipeng5 小时前
2024牛客暑期多校训练营1
算法
hetao17338375 小时前
2026-08-09~08-14 hetao1733837 的刷题记录
c++·算法
技术小黑5 小时前
RNN算法实战系列06 | LSTM 实现糖尿病探索与预测
rnn·算法·lstm
疯狂打码的少年6 小时前
【数据结构】二叉树的性质(五大性质+计算)
数据结构·笔记·算法
wabs6666 小时前
关于图论【A*算法 | 卡码网127.骑士的攻击的思考】
数据结构·算法·图论·卡码网·广搜的改进版
CIO_Alliance6 小时前
AI认知系列(3)| 数据、算法、算力、场景四要素协同
人工智能·算法·ipaas·系统集成·企业cio联盟·企业级ai化转型