LeetCode Linked List Cycle II
2015-12-17 10:41
295 查看
题目:
Given a linked list, return the node where the cycle begins. If there is no cycle, return
Note: Do not modify the linked list.
题意:
给定一个单链表,首先判断是否存在环,如果有环,那么就输出环开始的那个节点,如果没有环,那么就直接输出null。
题解:
此题和之前的判断单链表是否存在环类似,采用两个指针,一个指针走一步,另一个走两步,然后如果有环,那么那个走两步必定会追上走一步的,也就是这两个节点会碰撞在一起。然后就是判断环的初始点。这里存在一个数学公式:
碰撞点P到连接点的距离 = 头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是环开始的连接点。有数学公式可以证明。
寻找环的入口点: 当fast按照每次2步,slow每次一步的方式走,发现fast和slow重合,确定了单向链表有环路。接下来,让fast回到链表的头部,重新走,每次步长1,那么当fast和slow再次相遇的时候,就是环路的入口了。
证明:在fast和slow第一次相遇的时候,假定slow走了n步,环路的入口是在p步,那么
slow走的路径: p+c = n; c为fast和slow相交点 距离环路入口的距离
fast走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数
显然,如果从p+c点开始,slow再走n步的话,还可以回到p+c这个点。
同时,fast从头开始走,步长为1,经过n步,也会达到p+c这点。
显然,在这个过程中fast和slow只有前p步骤走的路径不同。所以当p1和p2再次重合的时候,必然是在链表的环路入口点上。
仔细理解下,还是可以懂得。
public class Solution
{
public ListNode detectCycle(ListNode head)
{
if(head == null || head.next== null)
return null;
if(head.next == head)
return head;
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
if(slow == fast)
break;
}
if(fast.next == null || fast.next.next == null)
return null;
slow = head;
while(slow != fast)
{
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
Given a linked list, return the node where the cycle begins. If there is no cycle, return
null.
Note: Do not modify the linked list.
题意:
给定一个单链表,首先判断是否存在环,如果有环,那么就输出环开始的那个节点,如果没有环,那么就直接输出null。
题解:
此题和之前的判断单链表是否存在环类似,采用两个指针,一个指针走一步,另一个走两步,然后如果有环,那么那个走两步必定会追上走一步的,也就是这两个节点会碰撞在一起。然后就是判断环的初始点。这里存在一个数学公式:
碰撞点P到连接点的距离 = 头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是环开始的连接点。有数学公式可以证明。
寻找环的入口点: 当fast按照每次2步,slow每次一步的方式走,发现fast和slow重合,确定了单向链表有环路。接下来,让fast回到链表的头部,重新走,每次步长1,那么当fast和slow再次相遇的时候,就是环路的入口了。
证明:在fast和slow第一次相遇的时候,假定slow走了n步,环路的入口是在p步,那么
slow走的路径: p+c = n; c为fast和slow相交点 距离环路入口的距离
fast走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数
显然,如果从p+c点开始,slow再走n步的话,还可以回到p+c这个点。
同时,fast从头开始走,步长为1,经过n步,也会达到p+c这点。
显然,在这个过程中fast和slow只有前p步骤走的路径不同。所以当p1和p2再次重合的时候,必然是在链表的环路入口点上。
仔细理解下,还是可以懂得。
public class Solution
{
public ListNode detectCycle(ListNode head)
{
if(head == null || head.next== null)
return null;
if(head.next == head)
return head;
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
if(slow == fast)
break;
}
if(fast.next == null || fast.next.next == null)
return null;
slow = head;
while(slow != fast)
{
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
相关文章推荐
- C++中 #define的用法
- python奥义
- SLAM: Ubuntu14.04_Kylin安装ROS-Indigo
- 我自己的Javascript 库,封装了一些常用函数
- Java工程师成神之路~
- Git别名调用自定义操作
- Hello ASP.NET5
- 下拉框
- 漫游kafka实战篇之搭建Kafka开发环境(3)
- jQuery validate基本原则
- 关于<:if>没有<c:else>解决方案
- IE7修改首页问题
- 面试题25:包含min函数的栈
- Android PopupWindow
- java平台概念
- myeclipse中,项目上有个叉报错,文件没有错误【解决方案】
- 基础数据结构之数组和链表(三)
- Hierarchyid 常用操作
- 第三届CCF计算机职业资格认证考试题解(C++)
- myeclipse怎么点击编辑区定位到项目所在的目录