有一个单向链表,链表当中有可能出现“环”,就像题图这样。如何用程序判断出这个链表是有环链表?
不允许修改链表结构。
时间复杂度O(n),空间复杂度O(1)。
记录两个算法
/**
* 判断单链表是否存在环
* @param head
* @return
*/
public static <T> boolean isLoopList(ListNode<T> head){
ListNode<T> slowPointer, fastPointer;
//使用快慢指针,慢指针每次向前一步,快指针每次两步
slowPointer = fastPointer = head;
while(fastPointer != null && fastPointer.next != null){
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
//两指针相遇则有环
if(slowPointer == fastPointer){
return true;
}
}
return false;
}
/**
* 找到有环链表的入口
* @param head
* @return
*/
public static <T> ListNode<T> findEntranceInLoopList(ListNode<T> head){
ListNode<T> slowPointer, fastPointer;
//使用快慢指针,慢指针每次向前一步,快指针每次两步
boolean isLoop = false;
slowPointer = fastPointer = head;
while(fastPointer != null && fastPointer.next != null){
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
//两指针相遇则有环
if(slowPointer == fastPointer){
isLoop = true;
break;
}
}
//一个指针从链表头开始,一个从相遇点开始,每次一步,再次相遇的点即是入口节点
if(isLoop){
slowPointer = head;
while(fastPointer != null && fastPointer.next != null){
//两指针相遇的点即是入口节点
if(slowPointer == fastPointer){
return slowPointer;
}
slowPointer = slowPointer.next;
fastPointer = fastPointer.next;
}
}
return null;
}