双指针概述
双指针是指使用两个指针协同解决问题。虽然单指针也能解决部分链表问题,但双指针在时间复杂度和空间复杂度方面通常更具优势。
基础双指针
以删除链表节点为例,使用单指针需要重新开辟空间;而使用双指针,假设分别为 p1 和 p2,p2 用于判断值是否符合条件,且保证 p2 一直是 p1 的下一位,用来决定 p1 是顺序移动还是跳过。可以设定一个哨兵位来辅助,将空间复杂度降为 O(1)。
快慢指针:寻找中点
快指针一次走两步,慢指针一次走一步。当快指针到达尾节点时,慢指针刚好到达中间节点。这比先遍历一遍获取长度再遍历一次的方法更高效。
快慢指针:检测环与入环节点
对于带环链表,需分两部分解决:判断是否有环,以及找到进入环的节点。
一、判断有环 快指针走两步,慢指针走一步。若两者相遇,说明链表中有环。若无环,快指针会先到达尾部。关于证明:当慢指针入环,快指针必在环中。设追击距离为 N,因速度差为 1,每次距离缩短一个节点,N 次后追上。
二、找入环节点 一个指针从原链表头节点开始每次一步,另一个指针从快慢指针相遇的节点开始同样每次一步。当这两个指针再次相遇,该节点即为入环节点。
证明逻辑如下: 设从头节点到入环节点的距离为 A,从入环节点到相遇节点的距离为 B,环长度为 C。 慢指针路程:A + B 快指针路程:A + B + n * C(n 为绕环圈数) 由于快指针速度是慢指针的两倍,故: 2 * (A + B) = A + B + n * C 化简得:A = n * C - B 即从头节点出发的指针走到入环节点的路程,等于从相遇节点出发绕环 n 圈回到入环节点的路程。
静态双指针:寻找倒数第 k 个节点
使用前指针和后指针。初始都指向头节点。根据 k 值,让前指针先运动 k 步。之后前指针和后指针同时运动,当前指针为空时,后指针指向的节点即为目标节点。
总结
双指针在遍历链表时比单指针更具优势,甚至可以达到一加一大于二的效果。空间复杂度能从 O(n) 降为 O(1)。此外,双指针能让链表的拼接、分割、合并等操作逻辑更清晰,在一次遍历中完成'遍历、判断、修改'等多步操作,避免重复遍历带来的性能损耗。


