LeetCode Hot100 - 滑动窗口篇

前言

挑战一个月刷完力扣的hot100,记录一下每题的思路~

这次是滑动窗口相关的题目

(1)3. 无重复字符的最长子串

双指针+变长 滑动窗口。若已知一个不重复子串(l到r),右指针扩充一个(r+1),只可能r+1 与某个k重复,因为l到k的字符不可能再产生新的更长不重复子串,于是将l循环收缩,直至新字符不重复(即l收缩到k+1),。然后r再继续往后扩充找新子串

java 复制代码
class Solution {
    Set<Character> set = new HashSet<>();
    public int lengthOfLongestSubstring(String s) {
        int res=0;
        // 每次右指针加一个
        for(int l=0,r=0; r<s.length(); r++){
            // 若当前元素已包含,循环缩短左边界,直至不在set中
            while(set.contains(s.charAt(r)))set.remove(s.charAt(l++));
            set.add(s.charAt(r)); // 添加当前元素
            res = Math.max(res,r-l+1); // 保留最长串
        }
        return res;
    }
}

(2)438. 找到字符串中所有字母异位词

①定长 滑动窗口。窗口长度始终为pLen,使用长度26的数组记录滑动窗口和p的字符数量,不断后移滑动窗口比较是否为异位词

java 复制代码
class Solution {
    int[] sCount = new int[26], pCount = new int[26]; // 计数
    List<Integer> res = new ArrayList<>();
    public List<Integer> findAnagrams(String s, String p) {
        int sLen=s.length(), pLen=p.length();
        if(sLen<pLen)return res; // 长度不足
        for(int i=0; i<pLen; i++){ // 初始化计数数组
            ++sCount[s.charAt(i)-'a'];
            ++pCount[p.charAt(i)-'a'];
        }
        if(Arrays.equals(sCount,pCount))res.add(0); // 异位词
        for(int i=0;i<sLen-pLen;i++){ // 滑动窗口长度始终为pLen
            --sCount[s.charAt(i)-'a'];
            ++sCount[s.charAt(i+pLen)-'a'];
            if(Arrays.equals(sCount,pCount))res.add(i+1);
        }
        return res;
    }
}

②双指针+变长 滑动窗口。用count记录p与滑动窗口差值 ,计数p初始化count。用双指针遍历,r右移取一位,维护count不小于0,循环收缩左边界。若滑动窗口长度与p同,且count不小于0,即每个元素相同,记录l

java 复制代码
class Solution {
    int[] count = new int[26]; // 计数,p与滑动窗口差值
    List<Integer> res = new ArrayList<>();
    public List<Integer> findAnagrams(String s, String p) {
        int sLen=s.length(), pLen=p.length();
        if(sLen<pLen)return res; // 长度不足
        for(char c:p.toCharArray()) ++count[c-'a']; // 初始化计数数组
        for(int l=0,r=0; r<sLen; r++){ // 双指针遍历
            --count[s.charAt(r)-'a']; // 取r
            // 循环收缩左边界,维持每个元素不小于0
            while(count[s.charAt(r)-'a']<0) ++count[s.charAt(l++)-'a'];
            // 长度相同,且每个元素不小于0,即个数相同
            if(r-l+1==pLen)res.add(l);
        }
        return res;
    }
}

总结

①滑动窗口常用于连续子串查找

②无重复字符的最长子串。用set和双指针+变长 滑动窗,每次移动右指针,若有重复就循环收缩左边界,直至不重复,再往右继续判断

③找到字符串中所有字母异位词。第一种定长 滑动窗口,滑动窗口长度始终与p同,用数组统计滑动窗口和p字符个数 ,若个数相同就记录结果,不断移动窗口判断。第二种双指针+变长 滑动窗口,与上题类似,count小于0就循环收缩左边界,若窗口长度等于p就记录l

相关推荐
倒头就睡的小比特4 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark4 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集
码流子4 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven4 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark4 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218614 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法