当前位置: 代码迷 >> 综合 >> LeetCode ---- 142、环形链表 II
  详细解决方案

LeetCode ---- 142、环形链表 II

热度:99   发布时间:2024-02-13 00:41:33.0

题目链接

思路:

采用双指针

准备一个快指针fast,一个慢指针slow,快指针一次走两步,慢指针一次走一步

初始时,快指针fast位于头节点的下一个节点,慢指针slow位于头节点

fast节点和slow节点同时开始向后走,若存在环,则一定会有一个时刻fast和slow指向同一个节点。若不存在,则最终fast走到null或者fast.next为null

若存在环,此时,slow和fast都位于环上

开始寻找第一个入环点:

寻找入环点的思路是:环的长度 + 未形成环的长度 = 链表总长度,第一个入环节点一定是未形成环路的最后一个节点的下一个节点,当拿到环的长度之后,先让一个节点从头走一个环的长度,然后另一个节点也从头开始,两个节点一起走,每次走一步,当相遇时,即为第一个入环点

这是因为此时这两个节点恰好走的长度为未形成环的长度,对于先走的那个节点来说,它走的总长度恰好为整个链表的长度,而后面走的节点,与先走的节点相遇时,走过的长度恰好是未形成环的长度,故相遇时即为第一个入环点。

例:

先判断是否有环路,s和f分别代表slow和fast,slow一次一步,fast一次两步,最终会在节点6处相遇

s  f                           
1->2->3->4             1->2->3->4       ?     ?   -> ... ->    ?     ? 7<-6<-5                7<-6<-5s,f

寻找入环点。f先走,一次一步,计算环的长度=6,f从头开始走6步,达到节点7。s从头开始,和f一起走,会在节点2相遇,节点2就是第一个入环节点

                s                   s,f
1->2->3->4      1->2->3->4        1->2->3->4  ?     ?   ->    ?     ?   ->      ?     ?7<-6<-5         7<-6<-5           7<-6<-5f               f     

代码:

    public ListNode detectCycle(ListNode head) {if (head == null || head.next == null) {return null;}// 快指针ListNode fast = head.next;// 慢指针ListNode slow = head;// 查看是否有环while (fast != null && fast.next != null) {if (slow == fast) {break;}slow = slow.next;fast = fast.next.next;}if (fast == null || fast.next == null) {return null;}int length = 1;fast = fast.next;// 计算环的长度while (fast != slow) {fast = fast.next;length++;}// fast从头开始往后走一个环的长度fast = head;while (length-- > 0) {fast = fast.next;}// slow从头开始,fast和slow同时一次一步,最终在入环点相遇slow = head;while (slow != fast) {slow = slow.next;fast = fast.next;}return slow;}class ListNode {int val;ListNode next;ListNode(int x) {val = x;next = null;}}