Voyz's Studio.

LeetCode算法笔记--环形链表II

字数统计: 398阅读时长: 1 min
2021/01/04 Share

LeetCode算法笔记-Day58

142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

1
2
3
4
5
6
Example1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

circularlinkedlist.png

1
2
3
4
5
6
Example2:

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

方法一:Floyd 算法(快慢指针)

Analyse:

  • 类似“追及问题”
  • 两个人在环形跑道上赛跑,同一个起点出发,一个跑得快一个跑得慢,在某一时刻,跑得快的必定会追上跑得慢的,只要是跑道是环形的,不是环形就肯定追不上。
  • 给定找到的相遇点,初始化额外的两个指针: ptr1 ,指向链表的头, ptr2 指向相遇点。然后,我们每次将它们往前移动一步,直到它们相遇,它们相遇的点就是环的入口,返回这个节点。  

Answer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
let _slow = head,
_fast = head,
_pre = head,
_meet;

// 确定是否有环,确定快慢指针相遇点
while(_fast){
if(_fast.next == null) return null;
_fast = _fast.next.next;
_slow = _slow.next;
if(_fast == _slow){
_meet = _fast;
break;
}
}

// 确定环入口
if(_fast){
while(true){
if(_pre == _meet) return _pre;
_pre = _pre.next;
_meet = _meet.next;
}
}else{
return null;
}

};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
CATALOG
  1. 1. LeetCode算法笔记-Day58
    1. 1.1. 142. Linked List Cycle II
    2. 1.2. 方法一:Floyd 算法(快慢指针)
      1. 1.2.1. Analyse:
      2. 1.2.2. Answer: