力扣142(Java)-环形链表Ⅱ(中等)

题目:

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。

示例3:

输入:head = [1], pos = -1

输出:返回 null

解释:链表中没有环。

提示:

  • 链表中节点的数目范围在范围 [0, 104] 内
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

进阶:你是否可以使用 O(1) 空间解决此题?

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

参考: 代码随想录视频讲解 和  文字讲解

本题的重点在两个方面:

1.判断是否有环:

力扣141.环形链表  解题思路一致,运用快慢指针:

  • 定义两个指针slow 和 fast,从头结点出发,使fast每次走两步,slow每次走一步;
  • 如果存在环,那快慢指针一定是在环中相遇,因为fast一定先进入环中,相对于slow来说,fast是以每次移动一个结点的速度来慢慢靠近slow的,要相遇一定是在环中相遇;
  • 移动的过程中,循环条件是:fast != null && fast.next != null,如果fast == slow 说明相遇了,则存在环,否则不存在。

2.计算入环的节点位置:

 会存在等式,快慢指针相遇时: 2 * (x + y) = n * (y +z) + x + y  == >   x = (n-1)(y+z) + z,需要注意,慢指针在绕环的第一圈时肯定会与快指针相遇。

  • n = 1 时, x = z,相遇的点是环形的入口点
  • n >= 1时,说明快指针在绕了n-1圈以后,在绕第n圈的时候绕了z距离与慢指针相遇了,相遇的点还是环形的入口点

这时设置第一个位置指针为inde1指向头节点,即index1 = head, 第二个位置指针index2指向相遇的节点 index2 = slow (这时候相遇了指向fast也可以),开始循环,循环条件是 index1 != index2:

  • 循环内,每次移动一步index1和index2,直到index1 = index2,找到入环点,返回index1 (index2也行);
  • 整个链表遍历完以后,无环,直接返回null。

代码:

 1 /**
 2  * Definition for singly-linked list.
 3  * class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public ListNode detectCycle(ListNode head) {
14         if (head == null || head.next == null) return null;
15         //先判断是否有环--快慢指针
16         ListNode fast = head, slow = head;
17         while (fast != null && fast.next != null){
18             fast = fast.next.next;
19             slow = slow.next;
20             //当存在环时找交点即入环点
21             while (fast == slow){
22                 ListNode index1 = head;
23                 ListNode index2 = slow;
24                 while (index1 != index2){
25                     index1 = index1.next;
26                     index2 = index2.next;
27                 }
28                 return index1;
29             }
30         }
31         return null;    
32     }
33 }

 

posted on 2023-05-05 10:54  我不想一直当菜鸟  阅读(32)  评论(0编辑  收藏  举报