题目:一个链表中包含环,请找出该链表的环的入口结点。
思路:首先第一步定义一快一慢的两个指针用来判断链表中是否存在环,如果链表中存在环,则两个指针最终会相遇,此时慢指针走过的节点正好等于环中节点的数目(两个指针不相遇的情况即链表中不存在环,直接返回 null);然后第二步把快指针移到头结点的位置,然后两个指针同时向前移到,两个指针再次相遇(肯定会相遇)的位置即为环入口节点的位置。
测试用例:
- 功能测试:链表中包含或者不包含环;链表中有多个节点或者只有一个节点。
- 负面测试:输入的链表头节点为 null 。
public class test_twenty_three {
public ListNode EntryNodeOfLoop(ListNode head){
if(head == null ||head.next == null)return null;
ListNode fast = head;
ListNode slow = head;
//用一快一慢两个指针来判断链表中有没有环
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(fast.val == slow.val){ //两个指针相遇即链表中有环,此时慢指针走过的节点长度正好等于环中节点的数目
fast = head; //把快指针重新放回头结点的位置
while(fast.val!= slow.val){ //然后两个指针同时往前走
slow = slow.next ;
fast = fast.next ;
}
}
if(slow.val == fast.val){ //直到两个指针相遇,此时的节点就是环的入口节点
return slow;
}
}
return null; //快指针追不上慢指针,证明链表中没有环,直接返回null
}
}