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