链表中环的入口节点
链表中环的入口结点
http://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
双指针解法
前置思想(以下长度指节点数量)
假设环的长度为k,链表长度为n,那么环的入口节点的前面的长度则为n-k。我们可以用两个指针left和right,先让right向前走k步,此时它距离链表终点的长度为n-k。然后我们再让这两个指针同步前进,当他们相遇时,所在节点即为环的入口。
- 首先利用快慢双指针,判断链表是否存在环(两个节点相遇时即存在环),不存在则立即返回null,否则接着下一步。
- 两个节点相遇时是在环里面,因此可以让慢节点静止不动,让快节点从慢节点开始向前移动并计数,当相遇时的计数便是环的长度。
- 利用left和right两个指针,left在起始点,让right先走k步,然后两个指针再同步前进,等到相遇时的节点即为环的入口。
public ListNode EntryNodeOfLoop(ListNode pHead) { if(pHead==null||pHead.next==null) return null; ListNode slow=pHead,fast=pHead.next.next; // check whether the list has circle while(slow!=null&&fast.next!=null&&slow!=fast){ slow=slow.next; fast=fast.next.next; } if(slow==null||fast==null) return null; // length of circle int k=1; fast=slow.next; while(slow!=fast){ k++; fast=fast.next; } slow=pHead; fast=pHead; // move forward k steps for(int i=0;i<k;i++){ fast=fast.next; } //move forward synchronously while(slow!=fast){ slow=slow.next; fast=fast.next; } return slow; }