一、双指针
虽然被叫做指针,但是是用数组的下标来锚定位置,其作用相当于"指针"。目前我所刷的题目中,大多是解决因暴力循环导致的超时问题,有了双指针就可以减少循环的次数。
划分区间
在数组中,解决数组数据分组的问题,例如在 移动零中,要将0和其他数据在数组中划分左右,且不改变原来数组中的数据的相对位置。这里不仅可以是把为零的移动,换个条件,比如将小于零的数往后移动,同样的原理,这里要注意的是,定义的两个指针(cur=0,dest= -1)的起始位置不同。因为当该数字不为零时,这两个指针要同时后移一位,若dest=0则会默认第一个数字归为非零数字,因为dest的位置及以前的数字都是处理过的非零数。
快慢指针
即一个走得慢的指针,一个走的快的指针,按照一定规律来完成一些任务。
目前了解到的使用场景有:
a. 判断是否有环(数组、链表)
链表:

利用快慢指针,即按照慢指针一次走一步,快指针一次走两步或n步的规律来遍历,如果出现了环,这两个指针一定会在某一处相遇。
数组: 数组的环与链表有所不同,因为数组没有next去指向下一个数据, 但如果是"数组模拟链表",nums[i]的下一个是nums[nums[i]],则没问题。可以参考 快乐数 这一题,指针本身就是数组的数据。
b. 找到链表的某个位置(中间位置或删除指定位置的节点)
在一个链表中,我要得到倒数第三个位置的数据,我可以让快指针先走两步,然后快慢指针一起走,当快指针走到头的时候,慢指针所指的位置就是倒数第三个数据的位置。可以参考 删除链表的倒数第 N 个结点。
c. 找到链表成环的入口

在一个有环链表中,a为链表首部到环入口的距离,b为链表入口到两指针相遇位置的距离,c为环的剩余长度 ,通过等式 fast走的长度是slow走的长度的2倍, 可以得出 a=c(k=1时)。 也就是说,从头结点走到入口的距离a,等于从相遇点出发环绕(k-1)圈后再走c距离到达入口。那么我让相遇的其中一个指针回到头节点,然后这两个指针再同步移动,再次相遇的节点就是入口。可以参考 环形链表 II。

d. 有序数组的去重 (参考: 删除有序数组中的重复项)
让fast指针去遍历,每当所遍历的数与slow当前所指的数不同,那么就可以让slow后移,然后进行赋值,这样不仅只需遍历一次数组,还可以在原数组修改,不需要利用额外的空间。
相向指针
这样运动的指针,通常用来缩小符合条件的区间,即找到了符合条件的边界,两个指针区间里面的都是符合条件的,那么就没必要再继续进行了。
可以参考如下的题目:
a. 三数之和
b. 四数之和
c. 盛最多水的容器
d. 有效三角形个数
做这些题目的时候,要注意是否要对原数组进行排序,通常情况下是配合这些数据的单调性以及题目本身的特性来解决。同时也要注意题目要的是累计结果,还是最值,如果是最值,要记得及时更新结果。