优先算法---双指针和滑动窗口

1.双指针

  • "双指针" 里的 "指针" 更多是一种逻辑概念,实际实现时通常是用两个变量(如left、right)来表示数组或字符串的下标,通过操作这些下标来模拟指针的移动,从而定位和处理元素。

常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。

  1. 对撞指针:⼀般⽤于顺序结构中,也称左右指针。
  • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
  • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循 环),也就是:
  • left == right (两个指针指向同⼀个位置)
  • left > right (两个指针错开)
  1. 快慢指针:⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。
  • 这种⽅法对于处理环形链表或数组⾮常有⽤。 其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。
  • 快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:
  • 在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

相关类型题目

盛水最多的容器

思路:

  • 体积(V)=高(H)*宽(W)
  • 一个容器能盛多高的水取决于左右两边最短的那块木板
cpp 复制代码
H=min(height[left],height[right])
  • H不变*W变窄->V变小,假如短的那一边是left,则left和[left+1,right-1]里元素相乘是没有意义的,因为提及一直在变小,而我们求的是最大的体积。
  • 所以我们初始化 left=0,right=长度-1,left和right会不断向中间靠拢,直到相遇才停止,每次移动之前会计算出体积,得出体积后让短的那一边向内靠拢,长的那一边则保持不动。
cpp 复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        // V=H*W;
        // H=min(height[left],height[right])
        // W=right-left
        // min和[left,right]中的任何一个数做容器,只有两种结果
        // 1.H不变*W变窄->V变小
        // 2.H变小*W变窄->V变小
        // 也就是说小的那一个没有和[left,right]里元素相乘的意义
        int left=0, right=height.size()-1;
        int maxV=0;
        while(left<right)
        {
            maxV=max(maxV,min(height[left],height[right])*(right-left));
            height[left]>height[right]?right--:left++;
        }

        return maxV;
    }
};

2.滑动窗口

  • 滑动窗口其实一种特殊的双指针。普通双指针往往是相向移动(left从左到右,right从右到左),通过缩小搜索范围来逼近答案;而滑动窗口的left和right则是同向移动(都从左到右),right负责 "扩张" 窗口,left负责 "收缩" 窗口,两者始终保持left ≤ right,共同维护一个连续的子区间。
  • 滑动窗口是一种在数组或字符串上高效处理连续子序列问题的算法思想,核心是通过维护一个动态变化的子区间(窗口),在遍历过程中调整窗口的边界(左、右指针),从而在 O (n) 时间复杂度内解决问题,避免暴力解法的 O (n²) 或更高复杂度。

核心思想

  1. 窗口定义:用两个指针(left、right)表示窗口的左、右边界,窗口范围为 [left, right](闭区间)。
  2. 进窗口:移动右指针,扩大窗口,直到满足某个条件(如子数组和 >= target)。
  3. 判断:根据题目条件判断是否需要缩小窗口以继续满足题目条件。
  4. 出窗口:移动左指针,在满足条件的基础上,缩小窗口以寻找最优解(如最短子数组)。
  5. 更新结果:过程中实时更新窗口内的关键信息(如和、哈希表计数等),有可能在进窗口的时候更新也有可能在出窗口的时候更新,位置不确定,视题目情况而定。
相关推荐
小熳芋4 小时前
验证二叉搜索树- python-递归&上下界约束
数据结构
不穿格子的程序员8 小时前
从零开始写算法——链表篇2:从“回文”到“环形”——链表双指针技巧的深度解析
数据结构·算法·链表·回文链表·环形链表
诺....8 小时前
C语言不确定循环会影响输入输出缓冲区的刷新
c语言·数据结构·算法
长安er10 小时前
LeetCode876/141/142/143 快慢指针应用:链表中间 / 环形 / 重排问题
数据结构·算法·leetcode·链表·双指针·环形链表
workflower10 小时前
PostgreSQL 数据库的典型操作
数据结构·数据库·oracle·数据库开发·时序数据库
仰泳的熊猫10 小时前
1140 Look-and-say Sequence
数据结构·c++·算法·pat考试
EXtreme3511 小时前
栈与队列的“跨界”对话:如何用双队列完美模拟栈的LIFO特性?
c语言·数据结构·leetcode·双队列模拟栈·算法思维
松涛和鸣11 小时前
29、Linux进程核心概念与编程实战:fork/getpid全解析
linux·运维·服务器·网络·数据结构·哈希算法
hweiyu0011 小时前
数据结构:有向图
数据结构