赞
踩
寻找环形链表入口点的第一步,要先判断该链表是否为环形链表,环形链表的尾指针指向的位置是不确定的,它可以在任何位置成环。
如下面这些图所示:
那么如何判断是否有环呢?我们可以采用双指针法,思路如下:
具体地,我们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,快、慢指针在位置 head。这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。
代码如下:
bool hasCycle(struct ListNode *head) { struct ListNode *slow=head; //慢指针 struct ListNode *fast=head; //快指针 //慢指针一次走一步,快指针一次走两步 while(fast!=NULL&&fast->next!=NULL) { slow=slow->next; fast=fast->next->next; if(slow==fast) { return true; } } return false; }
对于以上代码我们难免会提出以下两个问题;
答:
不会追不上。假设slow进环的时候,fast与slow的距离是N,紧接着追击的过程中(fast追slow)fast向前走两步,slow走一步,他们每次一走,它们之间的距离就会缩小1,由一开始相距N,到后面相距0。
 { struct ListNode* slow = head; //慢指针 struct ListNode* fast = head; //快指针 //慢指针一次走一步,快指针一次走两步 while (fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; if (slow == fast) { //相遇结点 struct ListNode*meet=fast; while(meet!=head) { meet=meet->next; head=head->next; } return meet; } } return NULL; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。