题目
有一个单向链表,链表中可能出现环,如何判断链表有环?
思路
快慢指针法
快指针一次走两步
慢指针一次一步
比较两个指针指向的节点是否相同,如果相同,则可以判断出链表有环。
代码
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null){
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while(slow != fast){
if(fast == null || fast.next == null){
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}
扩展1
如果成环,如何求出入环节点?
思路1
从链表头节点到入环点的距离,等于首次相遇点到入环点的距离。
代码1
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// 链表有环
if (slow == fast) {
// 快节点放到链表头
fast = head;
while (slow != fast) {
// 各前进一步
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
}
扩展2
如果链表有环,求环的长度
思路2
在快慢指针相遇后,让两个指针继续往前走,当两个节点再次相遇时,慢指针走过的距离就是环的长度。