[Leetcode] Linked list cycle ii 判断链表是否有环

Posted 王大咩的图书馆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Leetcode] Linked list cycle ii 判断链表是否有环相关的知识,希望对你有一定的参考价值。

Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull.

Follow up:
Can you solve it without using extra space?

题意:给定链表,若是有环,则返回环开始的节点,没有则返回NULL

思路:题目分两步走,第一、判断是否有环,第二若是有,找到环的起始点。关于第一点,可以参考之前的博客 Linked list cycle。这里主要分析在有环的情况下的第二步。

 

说明:在环中的前进方向是顺时针,起点为X,环入口为Y,相遇点在Z;无环X->Y的距离(节点数)为a,相遇点Z到Y的距离为b,环长r。

慢指针一次走一步,即slow=slow->next;快指针一次走两步,即fast=fast->next->next。第一相遇在Z点时,slow走过的距离为a+b,fast走过的距离为a+mr+b (m>=1),解释两个问题:一、为什么能遇到?二、为什么第一次相遇时,慢指针slow没有在环内走过n(0<n<m)圈?针对问题一,因为,快指针fast相对慢指针的的速度是1,即,可以看成,慢指针slow静止不动,而快指针fast以速度为1的情况下,在环内前行,所以能遇到。针对问题二,同样的道理,因为fast相对slow的速度是1,假设slow静止,则在fast以速度1完成一圈之前,肯定能遇到slow。

下面分析相遇时,走过的距离,即结点数。slow:a+b;fast:2*(a+b);所以2*(a+b)=a+mr+b(m>=1),故得到a+b=mr,即a=mr-b;所以讲slow放在X点,fast了依旧在Z点,只不过fast的速度降为1,这样,当X到Y的时候,fast也到Y,即得到环的入口点。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *detectCycle(ListNode *head) 
12     {
13         
14         ListNode *slow=head;
15         ListNode *fast=head;
16         //寻找第一个相遇点
17         while(fast&&fast->next)
18         {
19             slow=slow->next;
20             fast=fast->next->next;
21             if(slow==fast)
22                 break;
23         }
24         //不存在环
25         if(fast==NULL||fast->next==NULL)
26             return NULL;
27         //存在环,slow从头开始,fast从相遇点开始单步走,再次相遇即环的开始点
28         slow=head;
29         while(slow !=fast)
30         {
31             slow=slow->next;
32             fast=fast->next;
33         }
34         return slow;
35     }
36 };

//参考了Cyberspace_TechNode的博客!!!

 

 相关问题的扩展:参考南京大乱炖

1)环的长度是多少?

 方法一:从相遇点开始,让慢指针接着走,并计数,当慢指针slow和快指针再次相遇时,返回计数器的值就行

 方法二:第一次相遇后,让slow,fast继续走,记录到下次相遇时循环了几次。因为当fast第二次到达Z点时,fast走了一圈,slow走了半圈,而当fast第三次到达Z点时,fast走了两圈,slow走了一圈,正好还在Z点相遇。

2)如何将有环的链表变成单链表(即解除环)?

在本题的基础上,从环的入口开始,当指针的next为环的入口结点时,令next指向NULL即可。

以上是关于[Leetcode] Linked list cycle ii 判断链表是否有环的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——Linked List Cycle

LeetCode2.Linked List — Linked List Cycle II 链表环2

[leetcode]Linked List-237. Delete Node in a Linked List

LeetCode27.Linked List—Reverse Linked List l链表逆置

LeetCode 328. Odd Even Linked List

LeetCode OJ 328Odd Even Linked List