找到环的入口(开始入环的第一个结点)
要想找到环的入口总共有三步
1.创造一个环
2..判断是否有环,
3.如果有环,就可以找环的入口了。
由于前两步比较简单,这里只详细解释找环的入口这一步,代码中会每步详细实现。
关于数学:fast两步两步走,slow一步一步走,那么fast走过的路就是slow路程的两倍。就可以有下面的式子:式中 l 是环的长度
n+m+kl = 2(n+m)
kl = m+n
fast只多走了一圈,所以k=1;环的长度就是m+n
//创造环
public void creteLoop(){
ListNode cur = this.head;
while(cur.next!=null){
cur = cur.next;
}
cur.next = this.head.next.next;
}
//判断是否有环
public boolean hasCycle() {
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast) {
break;
}
}
if (fast == null || fast.next == null) {
return false;
}
return true;
}
//给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
public ListNode detectCycle(){
ListNode fast = this.head;
ListNode slow = this.head;
while(fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
break;
}
}
if(fast==null || fast.next==null){
return null;
}
slow = this.head;
while(slow!=fast){
fast = fast.next;
slow = slow.next;
}
return slow;
}