一.相关链接
视频链接:代码随想录:142.环形链表II
题目链接:142.环形链表II
二.心得体会
这道题是一道链表题,但他没有对头结点的操作,所以不用虚拟头结点。这道题要分两步进行,第一步是判断链表有没有环,这个只要让快慢指针同时从head出发,但fast每次走两步,slow每次走一步,最后如果fast能与slow相遇,那自然是有环链表,反之无环。
第二步是找到环的入口,这一步需要数学推导,我们知道fast走的总步数是slow的两倍,
即(x + y) * 2 = x + y + n (y + z),由此整理可知:x = (n - 1) (y + z) + z。其实意思就是如果要在入口处相遇,slow走过的x的长度就是fast在他们第一步在环内相遇点出发走了n-1圈后的长度,z就是他们第一步相遇后离入口的距离。看carl老师的图就一目了然了:
三.代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *detectCycle(ListNode *head) {ListNode* slow = head;ListNode* fast = head;int flag = 0; //记录有没有找到环的标记//第一步,观察有没有环,如果有则记录下相遇点while(fast!=NULL&&fast->next!=NULL){fast = fast->next->next;slow = slow->next;if(fast == slow){flag = 1;slow = head;break;}}if(flag == 0) return NULL;//第二步,找到环的入口while(fast != slow){slow = slow->next;fast = fast->next;}return fast;}
};