Typescript-Algorithms
    Preparing search index...

    滑动窗口题单 双指针题单 力扣题目 灵茶山艾府

    如果你刚开始刷题,还不熟悉基本编程语法常用库函数,推荐先刷力扣官方的入门题单

    有了一些简单题的积累,就可以开始刷我的题单啦~

    下面的题目已按照难度分排序,右侧数字为难度分。

    在刷题的过程中,如果遇到难度很大,题解都看不懂的题目,建议直接收藏,过段时间再来做。

    【套路】教你解决定长滑窗!适用于所有定长滑窗题目!

    不定长滑动窗口主要分为三类:求最长子数组,求最短子数组,以及求子数组个数。

    :滑动窗口相当于在维护一个队列。右指针的移动可以视作入队,左指针的移动可以视作出队

    一般要写 ans += left

    内层循环结束后,[left,right] 这个子数组是不满足题目要求的,但在退出循环之前的最后一轮循环,[left−1,right] 是满足题目要求的。由于子数组越长,越能满足题目要求,所以除了 [left−1,right],还有 [left−2,right],[left−3,right],…,[0,right] 都是满足要求的。也就是说,当右端点固定在 right 时,左端点在 0,1,2,…,left−1 的所有子数组都是满足要求的,这一共有 left 个。

    一般要写 ans += right - left + 1

    内层循环结束后,[left,right] 这个子数组是满足题目要求的。由于子数组越短,越能满足题目要求,所以除了 [left,right],还有 [left+1,right],[left+2,right],…,[right,right] 都是满足要求的。也就是说,当右端点固定在 right 时,左端点在 left,left+1,left+2,…,right 的所有子数组都是满足要求的,这一共有 right−left+1 个。

    思维扩展(选做)

    例如,要计算有多少个元素和恰好等于 k 的子数组,可以把问题变成:

    • 计算有多少个元素和 ≥k 的子数组。
    • 计算有多少个元素和 >k,也就是 ≥k+1 的子数组。

    答案就是元素和 ≥k 的子数组个数,减去元素和 ≥k+1 的子数组个数。这里把 > 转换成 ≥,从而可以把滑窗逻辑封装成一个函数 f,然后用 f(k) - f(k + 1) 计算,无需编写两份滑窗代码。

    总结:「恰好」可以拆分成两个「至少」,也就是两个「越长越合法」的滑窗问题。

    :也可以把问题变成 ≤k 减去 ≤k−1(两个至多)。可根据题目选择合适的变形方式。

    :也可以把两个滑动窗口合并起来,维护同一个右端点 right 和两个左端点 left1​ 和 left2​,我把这种写法叫做三指针滑动窗口

    刷题路线请看 如何科学刷题



    两个指针 left=0, right=n−1,从数组的两端开始,向中间移动,这叫相向双指针。上面的滑动窗口相当于同向双指针

    两个指针的移动方向相同(都向右,或者都向左)。

    相似题目:

    两个指针从数组中的同一个位置出发,一个向左,另一个向右,背向移动。

    思维扩展(选做)

    进阶

    :部分题目已整理到「§2.3.3 恰好型滑动窗口」中。

    思维扩展

    适用场景:按照题目要求,数组会被分割成若干组,每一组的判断/处理逻辑是相同的。

    核心思想

    • 外层循环负责遍历组之前的准备工作(记录开始位置),和遍历组之后的统计工作(更新答案最大值)。
    • 内层循环负责遍历组,找出这一组最远在哪结束。

    这个写法的好处是,各个逻辑块分工明确,也不需要特判最后一组(易错点)。以我的经验,这个写法是所有写法中最不容易出 bug 的,推荐大家记住。

    讲解

    做了一些题目后,请总结:滑动窗口和双指针的区别是什么?

    欢迎在评论区发表你的做题总结。

    • 滑动窗口相关数据结构题单 中的「单调队列」。
    • 双指针相关贪心题单 中的「单序列配对」和「双序列配对」。

    如何科学刷题?

    1. 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
    2. 二分查找(二分答案/最小化最大值/最大化最小值/第K小)
    3. 单调栈(基础/矩形面积/贡献法/最小字典序)
    4. 网格图(DFS/BFS/综合应用)
    5. 位运算(基础/性质/拆位/试填/恒等式/思维)
    6. 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
    7. 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
    8. 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
    9. 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
    10. 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
    11. 链表、二叉树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA/一般树)
    12. 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)

    如果你发现有题目可以补充进来,欢迎评论反馈。