0%

环形链表

题目

给定一个链表, 判断链表中是否有环, 若有则返回链表尾指向的结点.

解法一

遍历时使用 HashSet 保存所有节点, 若遍历到重复节点则返回该节点

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ListNode {
int val;
ListNode next;

ListNode(int x) {
val = x;
next = null;
}
}

public class CycleList {
public static ListNode hasCycle(ListNode head) {
HashSet<ListNode> nodeSet = new HashSet<>();

while (head != null) {
if (nodeSet.contains(head))
return head;
nodeSet.add(head);
head = head.next;
}

return null;
}
}

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ListNode:
def __init__(self, x):
self.val = x
self.next = None

class CycleList:
def hasCycle(self, head):
node_set = set()
while head:
if head in node_set:
return head
node_set.add(head)
head = head.next

return None

解法二

使用快慢指针, 该解法空间复杂度为 O(1) , 慢指针每次移动一个位置, 快指针每次移动两个位置, 该方法利用了两个定律:

  • 若链表中有环, 则两指针必相遇
  • 两指针相遇后, 快指针放回头结点, 从此快慢指针都每次移动一个位置, 两指针必在第一个入环节点处相遇

Java

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
class ListNode {
int val;
ListNode next;

ListNode(int x) {
val = x;
next = null;
}
}

public class CycleList {
public static ListNode hasCycle(ListNode head) {
if (head == null || head.next == null || head.next.next == null)
return null;

ListNode slow = head.next;
ListNode fast = head.next.next;

while (slow != fast) {
if (fast.next == null || fast.next.next ==null)
return null;
slow = slow.next;
fast = fast.next.next;
}

fast = head;

while (fast != slow) {
slow = slow.next;
fast = fast.next;
}

return slow;
}
}

Python

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
class ListNode:
def __init__(self, x):
self.val = x
self.next = None

class CycleList:
def hasCycle(self, head):
if head and head.next and head.next.next:
slow = head.next
fast = head.next.next

while slow != fast:
if fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
else:
return None

fast = head
while slow != fast:
slow = slow.next
fast = fast.next

return fast
else:
return None

例题 LeetCode # 141

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

示例 1:

1
2
3
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

1
2
3
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

1
2
3
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

要求:

空间复杂度为 O(1)

Java

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
class ListNode {
int val;
ListNode next;

ListNode(int x) {
val = x;
next = null;
}
}

public class CycleList {
public static boolean hasCycle(ListNode head) {
if (head == null || head.next == null || head.next.next == null)
return false;

ListNode slow = head.next;
ListNode fast = head.next.next;

while (slow != fast) {
if (fast.next == null || fast.next.next ==null)
return false;
slow = slow.next;
fast = fast.next.next;
}

return true;
}
}

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ListNode:
def __init__(self, x):
self.val = x
self.next = None

class CycleList:
def hasCycle(self, head):
if head and head.next and head.next.next:
slow = head.next
fast = head.next.next

while slow != fast:
if fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
else:
return False

return True
else:
return False