双指针
其实这是第一次接触这种算法概念,之前数据结构课堂上学习到的链表是非常基础和入门的,稍微进阶点的还得自己找资料学习,找题目练习。
双指针(Two Pointers):指的是在遍历元素的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的。如果两个指针方向相反,则称为「对撞时针」。如果两个指针方向相同,则称为「快慢指针」。如果两个指针分别属于不同的数组 / 链表,则称为「分离双指针」。
而在单链表中,因为遍历节点只能顺着 next
指针方向进行,所以对于链表而言,一般只会用到「快慢指针」和「分离双指针」。其中链表的「快慢指针」又分为「起点不一致的快慢指针」和「步长不一致的快慢指针」。这几种类型的双指针所解决的问题也各不相同。下面我们一一进行讲解。
起点不一致的快慢指针求解步骤 #
- 使用两个指针
slow
、fast
。slow
、fast
都指向链表的头节点,即:slow = head
,fast = head
。 - 先将快指针向右移动
n
步。然后再同时向右移动快、慢指针。 - 等到快指针移动到链表尾部(即
fast == Node
)时跳出循环体。
起点不一致的快慢指针适用范围 #
起点不一致的快慢指针主要用于找到链表中倒数第 k 个节点、删除链表倒数第 N 个节点等。
步长不一致的慢指针 #
步长不一致的慢指针:指的是两个指针从同一侧开始遍历链表,两个指针的起点一样,但是步长不一致。例如,慢指针
slow
每次走1
步,快指针fast
每次走两步。直到快指针移动到链表尾端时为止。
步长不一致的快慢指针求解步骤 #
- 使用两个指针
slow
、fast
。slow
、fast
都指向链表的头节点。 - 在循环体中将快、慢指针同时向右移动,但是快、慢指针的移动步长不一致。比如将慢指针每次移动
1
步,即slow = slow.next
。快指针每次移动2
步,即fast = fast.next.next
。 - 等到快指针移动到链表尾部(即
fast == None
)时跳出循环体。
步长不一致的快慢指针适用范围 #
步长不一致的快慢指针适合寻找链表的中点、判断和检测链表是否有环、找到两个链表的交点等问题。
分离双指针 #
分离双指针:两个指针分别属于不同的链表,两个指针分别在两个链表中移动。
分离双指针求解步骤 #
- 使用两个指针
left_1
、left_2
。left_1
指向第一个链表头节点,即:left_1 = list1
,left_2
指向第二个链表头节点,即:left_2 = list2
。 - 当满足一定条件时,两个指针同时右移,即
left_1 = left_1.next
、left_2 = left_2.next
。 - 当满足另外一定条件时,将
left_1
指针右移,即left_1 = left_1.next
。 - 当满足其他一定条件时,将
left_2
指针右移,即left_2 = left_2.next
。 - 当其中一个链表遍历完时或者满足其他特殊条件时跳出循环体。
分离双指针一般用于有序链表合并等问题。