找到环形链表的入口点
2016-06-15 12:51
633 查看
/**
* 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 * p=head;
ListNode * q=head;
while(q!=NULL&&q->next!=NULL)//第一次pq相遇
{
p=p->next;
q=q->next->next;
if(p==q)
break;
}
if(p==q)
{
p=head;
while(p!=q)//从起点开始,在入口点相遇
{
p=p->next;
q=q->next;
}
return p;
}
return NULL;
}
};
如下图所示,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的距离。
故两指针会在环开始位置相遇。
* 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 * p=head;
ListNode * q=head;
while(q!=NULL&&q->next!=NULL)//第一次pq相遇
{
p=p->next;
q=q->next->next;
if(p==q)
break;
}
if(p==q)
{
p=head;
while(p!=q)//从起点开始,在入口点相遇
{
p=p->next;
q=q->next;
}
return p;
}
return NULL;
}
};
如下图所示,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的距离。
故两指针会在环开始位置相遇。
相关文章推荐
- 【转】C语言快速幂取模算法小结
- ORA-01403: no data found
- python面试总结
- Excel Sheet Column Title
- 来自机房的第一篇博客
- 软件加密技术和注册机制加密基础
- iOS初探+load和+initialize
- hadoop、hbase、hive、zookeeper版本对应关系
- 第16周阅读程序——1(3)
- Material Design学习2
- Android关于Theme.AppCompat相关问题
- javascript [object,Object]
- 【CSS学习】CSS背景background、background-position使用详解
- java 中的Unsafe
- 神奇的e 死理性派的数学模型:拒绝掉前面37%=1/e的人(marriage problem)
- 应用直接退出
- (补)第七周阅读程序
- Material Designer效果展示
- 第16周阅读程序——1(2)
- SSM整合