题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路
快慢指针。 快指针步长2,慢指针步长1。如果存在环,快指针总能追上慢指针。 先找到快慢指针相遇的点p,并假设环的入口在点q。 从头节点到点q距离为A,q->p距离为B,p->q距离为C。 因为快指针是慢指针的两倍速,且在p点相遇,则可以得到等式 2(A+B) = A+B+C+B. 由等式可得,C = A。 此时slow指针已经在p,可以让fast返回头节点以步长1开始走,原slow指针继续保持原来的走法。 fast与slow再次相遇时,因为A=C,所以相遇的点一定是q。
时间复杂度O(n),空间复杂度O(1)。
代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
ListNode slow = pHead;
ListNode fast = pHead;
while(fast != null) {
if(fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
if(slow == fast) {
fast = pHead;
while(fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}
笔记
除了相遇,其余情况都返回null。