首页 > 其他分享 >刷题总结——滑动窗口与双指针

刷题总结——滑动窗口与双指针

时间:2024-10-25 21:58:54浏览次数:1  
标签:right 窗口 刷题 数组 滑动 left 指针

总结

问题类型

  • 滑动窗口(同向双指针)
    • 定长
    • 不定长
      • 求最长/最大
      • 求最短/最小
      • 求子数组个数
  • 单序列双指针(同向/相向)
    • 同向:快排求partition的Lobos算法
    • 相向:三数之和(保证有序)注意去重
  • 双序列双指针
    • 双指针
    • 子序列判断
  • 多指针
    • 荷兰旗low mid high 0 0 n初始化直到mid与high相遇

思考

  • 找到对应的循环不变量,在滑动窗口中通常是滑动窗口和之外区间的关系。
  • 注意循环不变量引起的开闭区间关系
  • “枚举右 选择左”原则
  • 有的时候要先排序,之后才会发现双指针关系
  • hash和计数规则的使用

滑动窗口

滑动窗口是一种同向的双指针。双指针的使用是一个for循环对指针right进行遍历,当指针right与指针left构成的窗口或者首尾两个元素满足某条件,就可以移动left指针,同时进行计数。

滑动窗口找一个符合某些性质的最长子串/连续子数组,因为left和right构成的范围必然是连续的。

定长滑动窗口

模版

  • 入:下标为 i 的元素进入窗口,更新相关统计量。如果 i<k−1 则重复第一步。
  • 更新:更新答案。一般是更新最大值/最小值。
  • 出:下标为 i−k+1 的元素离开窗口,更新相关统计量

不定长滑动窗口

求最大

其实就是r向右移动的时候扩大了范围,可能导致不满足约束条件,为此需要缩减左边的l。(不得不缩减,才移动左指针)

缩减l的while循环比较灵活,需要根据情况进行判断,如:

  • 允许k次操作来改变cnt
  • 计算首尾的差值,数学性质

其实就是计数方式需要灵活使用hash或者map或者cnt数组去存储。例如LC水果成篮,美丽度等问题

求最小

尽可能缩减,使得[l,r]范围数据尽量小一些。

注意学习76题最小覆盖子串中的优化方式:为了避免每次去判断52个字母的覆盖循环,可以使用一个额外的变量表示现有子串中字母出现次数小于reference中出现次数的数目,之后:

  • 遍历时,一旦次数达到要求less—
  • less=0说明满足了匹配情况,可以进一步判断子串是否为最短
  • 移动左侧的时候,一旦计数导致次数再次小于reference了,就less++

求子数组个数

两大类:

  • 越长越合法: ans += left
  • 越短越合法: ans += right - left + 1

即每次循环枚举右维护左的时候,右端点固定,构成有效子数组的左端点在[0, left-1]区间中(越长越合法)或者[left, right]区间(越短越合法)

注意判定的时候,一定要有一个数据结构储存滑窗中的数据,可能是单变量、hash数组,也可能是map,因为有的时候只有计数到0才会进行删除

单序列双指针

相向

  • 三数之和,注意对重复的判定
  • 有效三角形
  • 接雨水

同向

删除/交换元素

标签:right,窗口,刷题,数组,滑动,left,指针
From: https://www.cnblogs.com/hesun/p/18503351

相关文章

  • C语言指针练习
    题目如下:有1个班,3个学生,各学4门课,计算总平均分以及输出第n个学生的成绩示例代码如下:#include<stdio.h>intmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};......
  • 算法刷题记录(day1)
     前言 之前在LeetCode上断断续续刷了几百道题,但是很多题可能过一段时间后又忘了,打算从今天开始尽量保持每天刷题,同时记录下自己的刷题过程和对题目的理解,方便自己进行总结和复习。LC15.三数之和题目描述:给你一个整数数组 nums ,判断是否存在三元组 [nums[i],nums[j]......
  • 打卡信奥刷题(114)用C++工具信奥P1145[普及组/提高] 约瑟夫
    约瑟夫题目描述nnn个人站成一圈,从某个人开始数数,每次数到mmm的......
  • 软考刷题记录3
    1.选择题1.将一条指令的执行过程分解为取指、分析和执行三步,按照流水方式执行,若取指时间t取指=4△t、分析时间t分析=2△t、执行时间t执行=3△t,则执行完100条指令,需要的时间为()△t。A.200B.300C.400D.405答案:D流水线时间计算公式:T=第一条指令执行所需时间+(指令条数-1)×流水线......
  • 【优选算法】——滑动窗口(下篇)
    目录1、水果成篮2、找到字符串中所有字母异位词3、串联所有单词的子串4、最小覆盖子串1、水果成篮你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。你想要尽可能多地收集水果......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录二叉树的统一迭代法二叉树的统一迭代指的是二叉树的前序遍历,中序遍历,后序遍历使用迭代法实现时,在方法和形式上较为统一的迭代方法。二叉树的前序遍历,中序遍历,后序遍历之所以无法统一是......
  • 刷题总结——链表
    总论链表提供快速的前后访问和插入,不提供随机访问,要是需要随机访问需要结合hash实现链表反转类问题的关键是3个节点prevcurrnext之间的关系:由于反转的时候next会被改变,因此需要临时存储设置next的tmp=cur->next;之后可以反转,再更新prev和curr即可dummynode的引入,是......
  • C++ 内存管理 堆和栈、内存泄漏、内存分配、指针与内存、智能指针、malloc和free、new
    1.堆和栈的区别1.**管理方式**:-**栈**:自动管理。当函数调用时,局部变量会自动分配在栈上。函数执行完毕后,这些变量会自动释放。-**堆**:手动管理。程序员需要使用`new`来在堆上分配内存,并在不再需要时使用`delete`来释放。2.**使用方式和寿命**:-**栈**:用......
  • 关于C语言指针类型的总结
    前言我个人将目前在C语言中所遇到的指针归类为8种,至于为何写第九点,是因为我个人认为第九点极容易与第五点混淆,故总结如下:1.普通指针普通指针即最常见的如:int*、char*等甚至于也可将一个数组如arr[5]的数组名arr看作是指针类型(因为指针本质上就是地址,而arr是该数......
  • 刷题总结——树
    总结刷题中遇到的与树有关问题遍历问题前中后序遍历有递归与送代两种写法迭代时需要栈模拟,中序遍历单独注意写法(类似于模拟调用栈),后序遍历可以通过前序遍历+反转的方式实现题目LC编号注意事项前序递归144正常递归前序非递归144插入单个root后进行Stack......