Leetcode OJ: Linked List Cycle I/II

关于循环单链表的两题,先来简单的。

Given a linked list, determine if it has a cycle in it.

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  */
 9 class Solution {
10 public:
11     bool hasCycle(ListNode *head) {
12         if (head == NULL)
13             return false;
14         ListNode *p1 = head, *p2 = head;
15         while (p1 != NULL && p2 != NULL && p2->next != NULL) {
16             p1 = p1->next;
17             p2 = p2->next->next;
18             if (p1 == p2)
19                 break;
20         }
21         
22         if (p1 == NULL || p2 == NULL || p2->next == NULL) {
23             return false;
24         }
25         
26         return true;
27     }
28 };

问题进阶

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?

这是要找出环的起点。

先看看以上的结果,我们设从链表头到环起点的距离为t0,快慢指针相遇的点到环起点的距离为t1,快慢指针在环中走过的周期数分别为N1,N2,周期长度T

快指针路程T1 = t0 + t1 + N1*T

慢指针路程T2 = t0 + t1 + N2*T

快慢指针路程关系是T1=2*T2

结合以上式子,就得到t0 = (N1-2*N2)*T - t1

以上式子说明了什么?我们可以想象下当慢指针在相遇后继续前进t0步,那就是刚好到了环的起点了!

那怎么约束只走t0步呢?只需要再找一个指针,跟慢指针一样,每次一步,到环的起点的步数也是t0!

即两指针相遇时点就一定是环的起点了~上代码:

 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         if (head == NULL)
13             return NULL;
14         ListNode *p1 = head, *p2 = head;
15         while (p1 != NULL && p2 != NULL && p2->next != NULL) {
16             p1 = p1->next;
17             p2 = p2->next->next;
18             if (p1 == p2)
19                 break;
20         }
21         
22         if (p1 == NULL || p2 == NULL || p2->next == NULL) {
23             return NULL;
24         }
25         p2 = head;
26         while (p1 != p2) {
27             p1 = p1->next;
28             p2 = p2->next;
29         }
30         return p1;
31     }
32 };

 

posted @ 2014-03-23 16:15  flowerkzj  阅读(224)  评论(0编辑  收藏  举报