滑动窗口

定长窗口

字符串的排列

  1. 长度相同,才可能是排列
  2. 字符计数相同,则是一个排列
function checkInclusion(s1: string, s2: string): boolean {
    let [m, n] = [s1.length, s2.length]
    if (m > n) return false
 
    // 计数
    let s1Count = Array(26).fill(0)
    let s2Count = Array(26).fill(0)
    for (let i = 0; i < m; i++) {
        s1Count[s1[i].charCodeAt(0) - 97]++
        s2Count[s2[i].charCodeAt(0) - 97]++
    }
 
    function check() {
        return s1Count.every((v, i) => v === s2Count[i])
    }
 
    if (check()) return true
    for (let i = 0; i < n - m; i++) {
        s2Count[s2[i].charCodeAt(0) - 97]--
        s2Count[s2[i + m].charCodeAt(0) - 97]++
        if (check()) return true
    }
    return false
};

动态窗口

无重复字符的最长子串

  1. 左指针,顺序递增
  2. 右指针,字符不重复时递增
function lengthOfLongestSubstring(s: string): number {
    let [a, b] = [0, 0]
    let maxlen = 0
    let set = new Set()
 
    while (a < s.length) {
        while (b < s.length && !set.has(s[b])) {
            set.add(s[b])
            b++
        }
        maxlen = Math.max(maxlen, set.size)
        set.delete(s[a])
        a++
    }
    return maxlen
};