题目
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明:不允许修改给定的链表。
分析
快慢指针相遇点到环入口的距离 = 链表起始点到环入口的距离。(可推导)
一个环形链表(如图所示):{D,E,A,B,C,A,B,C,……}
其上存在两个指针,A指针移动速度是B指针的两倍。
A,B同时从节点1出发,所经过的节点如下:
快指针A:D->A->C->B
慢指针B:D->E->A->B
根据上图,我们可以计算出A、B行走的距离:
A = d+e+a+b+c+a
B = d+e+a
因为A的速度是B的2倍,那么A行走的距离也因该是B的2倍:
d+e+a+b+c+a = 2(d+e+a)
a+b+c = d+e+a
从上图可以看出,a+b+c正好是环的长度,而d+e+a则是B行进的距离。
又知,每次循环B移动一个单位距离,因此在不完美的环状表中,循环次数亦是等于环的长度。
根据上文公式,我们可以继续推导,即:
a+b+c = d+e+a
b+c = d+e
b+c是相遇点到环入口的距离
d+e是链表起点到环入口的距离
C
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
if(head==NULL||head->next == NULL)
return false;
struct ListNode *slow, *fast;
slow = head;
fast = head;
while(fast->next&&fast->next->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
struct ListNode *p=head;
while (p!=slow)
{
p = p->next;
slow = slow->next;
}
return p;
}
}
return false;
}
python
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None or head.next is None:
return None
fast = slow = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
if slow ==fast:
p = head
while p != slow:
p = p.next
slow = slow.next
return p
return None