链表中环的入口结点
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路
方法一:如果可以考虑额外空间复杂度,可以使用哈希表来实现,也就是从链表的头结点开始遍历,每遍历一个节点就在哈希表中记录这个节点。如果一个链表无环,可以知道走到结尾处也不会出现重复的节点,此时返回空。如果有环,hash表肯定能找到
最优解额外空间复杂度为o(1):
方法二:从头节点开始用快慢两个指针进行遍历,快指针一次走两步,慢指针一次走一步。如果一个链表无环,快指针会迅速发现末尾为空的位置返回空即可;如果有环,快慢指针会在某个时刻相遇,到达相遇点时,我们让快指针指向链表头节点,慢指针指向相遇点,两个指针速度均为1,沿着链表前进,最后它们相遇的位置,就是环入口节。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead){
if(pHead == null || pHead.next == null){//很重要
return null;
}
ListNode fast = pHead;
ListNode slow = pHead;
while(fast != null || fast.next != null){//注意while语句的判断条件
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
fast = pHead;
//相遇之后找入环节点
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}