Linked List Cycle II
2016-04-17 21:27
211 查看
仍然使用龟兔赛跑方法,但还需要在这之上根据证明推倒算法:
不难证明:两指针第一次相遇的地方位于“当慢指针进入环时,快环相对于环起始点的位置”的相反位。例如:
假设一开始Fast和Slow从开始位置开始遍历这个链表。
令m = 3,表示经过三步,Slow结点到达环的起始位置,此时Fast在环的第m个位置,因为Fast比Slow多走了m步
根据刚才的结论,当Slow停在起始位置,Fast停在m位置,两个链表最后会在n-m位置相遇
此时把Slow移到头结点位置,两个结点都是要经过m步,才刚刚好到达环的起始位置。
所以根据这个结论可以写以下算法:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next==NULL || head->next->next==NULL) return NULL;
ListNode* p=head;
ListNode* q=head;
while(1) {
if(p->next == NULL) return NULL;
p = p->next;
q = q->next;
if(p->next != NULL) {
p = p->next;
if(p == q) {
break;
}
}
}
q = head;
while(q!=p) {
p = p->next;
q = q->next;
}
return q;
}
不难证明:两指针第一次相遇的地方位于“当慢指针进入环时,快环相对于环起始点的位置”的相反位。例如:
假设一开始Fast和Slow从开始位置开始遍历这个链表。
令m = 3,表示经过三步,Slow结点到达环的起始位置,此时Fast在环的第m个位置,因为Fast比Slow多走了m步
根据刚才的结论,当Slow停在起始位置,Fast停在m位置,两个链表最后会在n-m位置相遇
此时把Slow移到头结点位置,两个结点都是要经过m步,才刚刚好到达环的起始位置。
所以根据这个结论可以写以下算法:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next==NULL || head->next->next==NULL) return NULL;
ListNode* p=head;
ListNode* q=head;
while(1) {
if(p->next == NULL) return NULL;
p = p->next;
q = q->next;
if(p->next != NULL) {
p = p->next;
if(p == q) {
break;
}
}
}
q = head;
while(q!=p) {
p = p->next;
q = q->next;
}
return q;
}
相关文章推荐
- 出差(2~十)
- 【机房重构】Sqlhelper类解读
- 欢迎使用CSDN-markdown编辑器
- SSL学习
- Dom4j的应用 xml的使用 android
- ZOJ 1755
- LeetCode------ZigZag Conversion
- [LeetCode]54. Spiral Matrix
- copy和strong的选择
- Linux内核分析:实验八
- iOS开发 粗解UIDynamicAnimator
- 保持代码健壮性的小技巧
- 什么是C++虚函数、虚函数的作用和使用方法
- 多层网络和反向传播笔记
- IOS开发之代理的设计小技巧
- 抽象类和接口的区别
- 盒子模型 标准W3C盒子模型和IE盒子模型CSS布局经典盒子模型
- crontab一句话后门分析
- 自考总结之信息资源管理
- iOS App开发那些事:如何选择合适的人、规范和框架?