题目描述
描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
输入描述:
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台将这2个会组装成一个有环或者无环单链表
返回值描述:
返回链表的环的入口结点即可。而我们后台程序会打印这个节点
示例1
输入:{1,2},{3,4,5}
返回值:3
说明:返回环形链表入口节点,我们后台会打印该环形链表入口节点,即3
示例2
输入:{1},{}
返回值:"null"
说明:没有环,返回null,后台打印"null"
示例3
输入:{},{2}
返回值:2
说明:只有环形链表节点2,返回节点2,后台打印2
思路
1.遍历链表,使用HashSet存储,如果在添加某个结点失败,说明该结点是环的入口。
2.快慢指针。快慢指针先指向头节点,然后快指针每次走两步,慢指针每次走一步,这样他俩一定会在环中的某一结点相遇。相遇后,慢指针不动,快指针指向头结点,此时慢指针和快指针距离环入口结点的距离相等,所以让快慢指针同时前进一步直到他们再次相遇,此时相遇的结点就是入口节点。
解答
解答一
public ListNode EntryNodeOfLoop(ListNode pHead) {
HashSet<ListNode> set = new HashSet<>();
while (pHead != null){
boolean res = set.add(pHead);
if (res == false){
return pHead;
}
pHead = pHead.next;
}
return pHead;
}
解答二
public ListNode EntryNodeOfLoop(ListNode pHead) {
if (pHead == null || pHead.next == null)
return null;
ListNode fast = pHead, slow = pHead;
do {
fast = fast.next.next;
slow = slow.next;
}while (fast != slow);
fast = pHead;
while (fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}