题干:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:
思路有2:
1.利用额外的空间记录链表中的节点,出现重复的节点便是循环入口;
2.利用快慢指针,,慢指针一次移动一个节点,快指针是慢指针的速度二倍。二者相遇后,再取一个指针从表头出发,另外一个从相遇节点出发,二者再次相遇的点便是链表中的环入口。
这里的思路1,较为简单,直接利用HashMap进行记录即可,关键是思路2,较为抽象,这里给出一个简单的证明:
具体解法:
方法1:
import java.util.HashMap;
/*
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:利用HashMap存放每个节点,一旦出现重复节点,那么便是环的入口
*/
public class ietm56 {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
HashMap<ListNode,Integer> map = new HashMap<>();
while (pHead!=null){
if(map.get(pHead)==null){
map.put(pHead,1);
}
else {
return pHead;
}
pHead=pHead.next;
}
return null;
}
}
方法2:
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){
fast = fast.next.next;//快指针一次走两个结点
slow = slow.next;//慢指针一次走一个结点
if(fast == slow){//找到相遇点,开始找循环入口
ListNode slow2 = pHead;
while(slow2 != slow){
slow2 = slow2.next;
slow = slow.next;
}
return slow2;
}
}
return null;
}
}