LeetCode 142环形链表 II
300 Words|Read in about 2 Min|本文总阅读量次
leetcode第142题,环形链表2。采用双指针的算法来完成。
LeetCode 142环形链表 II
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0
开始)。如果 pos
是 -1,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
1输入:head = [3,2,0,-4], pos = 1
2输出:返回索引为 1 的链表节点
3解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
1输入:head = [1,2], pos = 0
2输出:返回索引为 0 的链表节点
3解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
1输入:head = [1], pos = -1
2输出:返回 null
3解释:链表中没有环。
提示:
- 链表中节点的数目范围在范围
[0, 104]
内 -105 <= Node.val <= 105
pos
的值为-1
或者链表中的一个有效索引
**进阶:**你是否可以使用 O(1)
空间解决此题?
思路
对于环形链表有通用解法,使用Floyd算法。
- 这里使用的还是双指针,与之前不同的是,这里的双指针的快慢指针,快指针每次移动2个单位,慢指针每次移动1个单位
- 如果存在环,这两个指针必定会相遇,即指针的地址会相同,且会相差
m
个环的距离 - 在这个基础上,一旦找到环。立刻把慢指针移动链表头部,这个时候并且继续移动两个快慢指针,快慢指针每次移动1个单位。
- 直接再一次两个指针相遇,那么指针相遇的位置,即指针的位置则为环的开始。
解题
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 */
12public class Solution {
13 //快慢双指针相遇,慢指针移至链首,快慢指针以相同速度再次相遇的点为环的开始
14 public ListNode detectCycle(ListNode head) {
15 if(null == head) return null;
16 ListNode slow = head;
17 ListNode fast = head;
18 boolean existCycle = false;
19 while(null != fast.next && null != fast.next.next)
20 {
21 fast = fast.next.next;
22 slow = slow.next;
23 if(fast == slow)
24 {
25 existCycle = true;
26 break;
27 }
28 }
29
30 if(existCycle)//存在环
31 {
32 slow = head;
33 while(slow != fast)
34 {
35 slow = slow.next;
36 fast = fast.next;
37
38 }
39 return slow;//返回环的起点
40 }
41 return null;
42 }
43}