您的位置:首页 > 其它

[leetcode] 142.Linked List Cycle II

2015-08-20 13:34 274 查看
题目:

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?

题意:

给定一个链表,如果有环的话,找出环的开始节点,否则返回NULL。

思路:

首先来确定是否存在环,依旧使用一快一慢两个指示器,一个每次往前走两步,一个每次往前走一步,如果遇到NULL了,说明能够访问到链表的结尾,所以不存在环。否则的话两者一定在环中相遇。

假设慢节点走了k步到达环的入口处,那么快结点此时已经在环中走了k步,假设环的长度是length,并且假设k = m*length + n,那么此时快结点离环的入口节点的距离是n。接下来慢节点也会进入环,并且按照运动方向,此时快结点与慢节点其实相距是length - n的长度,接下来就是追逐戏,快结点去追慢节点,慢节点每走一步,快结点会走两步,所以它们之间的距离就会少一,所以追逐了length - n步之后,它们就会在环中相遇了。此时这两个节点离环的入口位置距离是n。而我们知道从链表的头结点倒环的入口距离是k,而k = m*length + n,那么此时我们让快结点从链表头结点开始,但是此时快结点变成跟慢节点一样的速度,那么两个节点一定会在环的入口处相遇,因为快结点到达入口时,慢节点正好在里面绕了m圈后,又走了n步,正好就在环的入口处。

以上,代码如下:

/**
1. Definition for singly-linked list.
2. struct ListNode {
3.     int val;
4.     ListNode *next;
5.     ListNode(int x) : val(x), next(NULL) {}
6. };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next == NULL)return NULL;
ListNode *node1 = head->next, *node2 = head->next->next;
while(node2 != NULL && node1 != node2) {
node1 = node1->next;
node2 = node2->next;
if(node2 == NULL)break;
node2 = node2->next;
}
if(node2 == NULL)return NULL;
ListNode *h2 = head->next;
node1 = node1->next;
while(node1 != node2) {
node1 = node1->next;
h2 = h2->next;
}
ListNode *h1 = head;
while(h1 != h2) {
h1 = h1->next;
h2 = h2->next;
}
return h1;
}
};


2.思路二,同样是快慢节点先在环中相遇。然后我们找出环的长度,让慢节点不动,快结点继续一步一步的走,直到快结点再次走到慢节点所在的位置,统计出长度length。接下来,让先行节点先走length,然后后行节点也开始往前走,所以当两者再次相遇的时候,正好是在环的入口处。因为先行节点正好多走了一个环的长度。

以上。

代码如下:

/**
* 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) {
if(head == NULL || head->next == NULL)return NULL;
ListNode *node1 = head->next, *node2 = head->next->next;
while(node2 != NULL && node1 != node2) {
node1 = node1->next;
node2 = node2->next;
if(node2 == NULL)break;
node2 = node2->next;
}
if(node2 == NULL)return NULL;
ListNode *h2 = head->next;
node1 = node1->next;
while(node1 != node2) {
node1 = node1->next;
h2 = h2->next;
}
ListNode *h1 = head;
while(h1 != h2) {
h1 = h1->next;
h2 = h2->next;
}
return h1;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: