快慢指针:双指针的一种。在链表中设置两个指针,不同步地遍历链表。可以在两个指针之间制造我们需要的距离。
LeetCode 141 环形链表 easy
题面纯属为了测试时修改样例用,只要按判断链表中是否存在环做就行了。
思路一:Hash
最容易想到的思路应该是哈希法,每当一个链表被访问过了,就把它记录在哈希表里,当链表中存在环时就会有重复访问的节点,代码略。
思路二:快慢指针
设置两个指针,fast和slow,步长分别为2,1。如果将链表比作跑道,这就意味着fast的速度是slow的两倍。而当链表中存在环时,fast再快也不会访问到NULL,而又因为fast速度快,早晚会超过slow一整圈,即一段时间后两指针会重新相遇(fast==slow)。

1 class Solution {
2 public:
3 bool hasCycle(ListNode *head) {
4 if(NULL==head||NULL==head->next)
5 return false;
6
7 ListNode *slow=head;
8 ListNode *fast=head;
9
10 while(NULL!=fast&&NULL!=fast->next)
11 {
12 fast=fast->next->next;
13 slow=slow->next;
14 if(fast==slow)
15 return true;
16 }
17 return false;
18 }
19 };
LeetCode 876 链表的中间节点 easy
快指针的速度是慢指针的两倍,当快指针到达终点时,慢指针正好指向链表的中间节点。

1 class Solution {
2 public:
3 ListNode* middleNode(ListNode* head) {
4 ListNode *slow=head;
5 ListNode *fast=head;
6 if(NULL==head||NULL==head->next)
7 return head;
8 while(1)
9 {
10 fast=fast->next;
11 if(NULL==fast->next)
12 return slow->next;
13 slow=slow->next;
14 fast=fast->next;
15 if(fast->next==NULL)
16 return slow;
17 }
18 }
19 };
LeetCode 19 删除链表的倒数第N个节点 medium
让快指针先行N步,然后以相同速度遍历链表,当快指针到达终点时,慢指针正好指向快指针前的第N个元素。

1 class Solution {
2 public:
3 ListNode* removeNthFromEnd(ListNode* head, int n) {
4 ListNode *slow=head;
5 ListNode *fast=head;
6 for(int i=0;i!=n;++i)
7 fast=fast->next;
8 if(NULL==fast)
9 return head->next;
10 while(NULL!=fast->next)
11 {
12 fast=fast->next;
13 slow=slow->next;
14 }
15 slow->next=slow->next->next;
16 return head;
17 }
18 };
来源:https://www.cnblogs.com/CofJus/p/11992789.html
