前言
哪些情况下使用双指针算法:
1.有序数组或有序链表的查找:当给定一个有序数组或有序链表,并需要在其中查找某个目标元素时,可以使用双指针算法。通过将两个指针分别指向数组或链表的开头和末尾,根据目标元素与当前指针所指元素的大小关系,逐步缩小查找范围,直到找到目标元素或确定不存在。
2.两数之和:当需要在数组或列表中找到两个数的和等于特定目标值时,可以使用双指针算法。通过将两个指针分别指向数组或列表的开头和末尾,根据两个指针所指元素的和与目标值的大小关系,逐步向中间靠拢,直到找到满足条件的两个数或确定不存在。
3.三数之和:当需要在数组中找到三个数的和等于特定目标值时,可以使用双指针算法。通过固定一个数,然后使用双指针在剩余的数组元素中查找满足条件的另外两个数。根据三个数的和与目标值的大小关系,移动指针以逐步缩小查找范围,直到找到所有满足条件的三个数或确定不存在。
4.两个有序数组的合并:当需要将两个有序数组合并为一个有序数组时,可以使用双指针算法。通过使用两个指针分别指向两个数组的开头,比较两个指针所指元素的大小,并将较小的元素放入合并后的数组中,然后移动相应的指针,直到合并完成。
5.链表操作:在链表相关的问题中,双指针算法也经常被使用。例如,确定链表是否存在环、找到链表的中间节点、反转链表等操作都可以使用双指针算法。
双指针
常见的双指针有三种形式,⼀种是对撞指针,⼀种是左右指针,同向双指针(滑动窗口)。
1.对撞指针
⼀般用于顺序结构中,也称左右指针。
- 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
- 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是:
- left == right (两个指针指向同⼀个位置)
- left > right (两个指针错开)
2.快慢指针
又称为龟兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。这种⽅法对于处理环形链表或数组⾮常有⽤。其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:
- 在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。
3.滑动窗口(同向双指针)
滑动窗口是一种常用的双指针算法,它可以用于解决一类涉及连续子数组或子字符串的问题。滑动窗口算法通过维护一个窗口,通过移动窗口的左右边界来寻找满足特定条件的子数组或子字符串。
滑动窗口算法的基本思想如下:
-
1.初始化左指针left和右指针right,将它们都指向窗口的起始位置。
-
2.当满足特定条件时,移动右指针right,扩大窗口范围。
-
3.当不满足特定条件时,移动左指针left,缩小窗口范围。
-
4.在移动左右指针的过程中,不断更新记录的结果,例如最短子数组的长度、最大子数组的和等。
-
5.重复步骤2和步骤3,直到右指针达到数组或字符串的末尾。
滑动窗口算法的优点在于它可以在一次遍历的过程中解决问题,而不需要嵌套循环。这样可以大大提高算法的效率。
小技巧:
哪些情况下考虑滑动窗口:
- 题目中涉及处理数组中连续元素时
- 题目中涉及处理连续字符串时
注意
- 双指针是一种思想,不一定非要定义指针进行解题,一般情况下可以用数组下标代替,有时甚至可以用数组值代替。
- 找规律,把不符合/符合题目情况的规律找出来,从而找到切入口,提高算法效率。