首页 > 其他 > 详细

142. 环形链表 II

时间:2019-10-31 18:00:55      阅读:97      评论:0      收藏:0      [点我收藏+]

题目描述:
Given a linked list, return the node .where the cycle begins. If there is no cycle, return null.Follow up:Can you solve it without using extra space?

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  */

思路1:

先求出环中的节点个数n,然后先让快指针先走n步。然后快慢指针一起走。

 1 class Solution {
 2 public:
 3     ListNode *detectCycle(ListNode *head) {
 4 
 5         if(head==nullptr || head->next==nullptr)
 6             return nullptr;
 7         ListNode *fast = head;
 8         ListNode *slow = head; 
 9         //这个循环的主要目的是为了判断是否存在环
10         while(fast->next && fast->next->next)//不是环的话,会遇到nullptr结点 
11         { 
12             fast = fast->next->next;
13             slow = slow->next;
14             if(fast == slow)//是环的话,快慢指针会相遇
15                 break;
16         }
17         //好的编程习惯:当循环中有好几处能使循环中断的情况,循环中断后,
18         //应该首先判断是那种情况引起的循环中断
19         if(fast->next==nullptr || fast->next->next==nullptr)
20             return nullptr;
21         fast = fast->next; 
22         int cnt = 1;//cnt为环的节点个数,也即从环中一个结点出发又回到原地需要移动的次数
23         while(fast != slow) 
24         {
25             fast = fast->next;
26             ++cnt;//每移动一次cnt的状态更新一次
27         }
28         fast = head;
29         slow = head; 
30         for(int i = 0; i < cnt; ++i)
31             fast = fast->next; 
32         while(slow != fast) 
33         {
34             slow = slow->next;
35             fast = fast->next;
36         }
37         return slow;
38     }
39 };

 

思路2:

如下图所示,X,Y,Z分别为链表起始位置,环开始位置和两指针相遇位置,则根据快指针速度为慢指针速度的两倍,可以得出:

2*(a + b) = a + b + n * (b + c);a=(n - 1) * b + n * c = (n - 1)(b + c) +c;注意到b+c恰好为环的长度,故可以推出,如将此时两指针分别放在起始位置和相遇位置,并以相同速度前进,当一个指针走完距离a时,另一个指针恰好走出 绕环n-1圈加上c的距离。故两指针会在环开始位置相遇。

技术分享图片

代码:

 1 class Solution {
 2 public:
 3     ListNode *detectCycle(ListNode *head) {
 4 
 5         if(head==nullptr || head->next==nullptr)
 6             return nullptr;
 7         ListNode *fast = head;
 8         ListNode *slow = head; 
 9         //这个循环条件只是为了保证循环的进行,如果一个链表中前进能
10         //遇到nullptr结点,则一定不是环,用fast->next->next!=nullptr只是
11         //为了如果不是环的话及早发现,没有什么
12         //换成while(fast && fast->next)也可以,不过这样的话,不是环的话
13         //得多进行一个循环次数
14         while(fast->next && fast->next->next)//不是环的话,会遇到nullptr结点 
15         { 
16             fast = fast->next->next;
17             slow = slow->next;
18             if(fast == slow)//是环的话,快慢指针会相遇
19                 break;
20         }
21         //好的编程习惯:当循环中有好几处能使循环中断的情况,循环中断后,
22         //应该首先判断是那种情况引起的循环中断
23         if(fast->next==nullptr || fast->next->next==nullptr)
24             return nullptr;
25         slow = head; 
26         while(slow != fast) 
27         {
28             slow = slow->next;
29             fast = fast->next;
30         }
31         return slow;
32     }
33 };

 

142. 环形链表 II

原文:https://www.cnblogs.com/zjuhaohaoxuexi/p/11772215.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!