题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路
思路1:使用HashMap。用Map保存链表中每个节点出现的次数,第一次出现2次的节点就是我们所要找的环的入口结点,如果没有找到,返回null。
思路2:快慢指针。将该问题分解为3个步骤:
- 1)确定链表是否有环:通过两个快慢指针确定
- 2)得到环中结点的数目n:指针走1圈,边走边计数,再次回到这个结点时便得到环中的结点数目。
- 3)找到环路的入口:从头结点开始,通过两个相差为n的快慢指针来得到(即转化为寻找链表中倒数第n个结点)
解法1
import java.util.*; public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { Map<ListNode,Integer> map = new HashMap<>(); ListNode cur = pHead; while (cur != null){ map.put(cur,map.getOrDefault(cur,0) + 1); if (map.get(cur) == 2){ return cur; } cur = cur.next; } return null; } }
☆解法2
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null) return null; ListNode fast = pHead; ListNode slow = pHead; boolean flag = false; // 1.判断链表中是否有环 while (fast != null && fast.next != null){ // 条件很重要!! 如果链表没有环,且结点数是偶数或奇数 slow = slow.next; fast = fast.next.next; if (fast == slow){ flag = true; break; } } if (!flag){ return null; }else{ // 2.得到环中结点的数目 int count = 1; // 统计环中结点数目。 应该初始化为1 ,因为先走了1步 fast = fast.next; while (fast != slow){ fast = fast.next; count++; } // 3.找到环中的入口结点 fast = slow = pHead; for (int i = 0; i < count; i++) { fast = fast.next; } while (fast != slow){ fast = fast.next; slow = slow.next; } return fast; } } }