- 题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
- 思路
令p1和p2指向头节点,p1一次走一步,p2一次走2步。
1.找相遇点
2.找环入口
如图:p1,p2在C点相遇。 p2=2p1
设ABC=x,ABCBC=2x.(肯定是p1走到C时,p2已经走了一圈了,p2比p1快一倍)
p1,p2共同走的是ABC,即ABCBC(p2走的路)-ABC(p1走的路)=CBC(一个环的距离)=2x-x=x。
因为ABC=CBC=x,所以我们知道ABC的距离就相当于一个环。ABC和CBC的共同距离是BC这一段,所以AB=CB。
走到相遇点时,我们让p2重新指向头节点,p1在相遇点不动,当两个指针再次相遇的时候就是环的入口了。
- 代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead){
//头节点为空或头节点下一个节点为空,返回null
if(pHead == null || pHead.next == null)
return null;
//令p1,p2指向头节点
ListNode p1 = pHead;
ListNode p2 = pHead;
//当p2和p2的下一个节点不为空
while(p2 != null && p2.next != null){
//p1走一步
p1 = p1.next;
//p2走两步
p2 = p2.next.next;
//当p1=p2,即到相遇点停止
if(p1 == p2)
break;
}
//令p2重新指向头节点
p2 = pHead;
//当p1和p2不相等,即没到环入口时
while(p1 != p2){
//p1走一步
p1 = p1.next;
//p2走一步
p2 = p2.next;
}
return p1;
}
}