快慢指针while循环中要判断slow是否等于fast.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> visited = new HashSet<ListNode>();

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

return null;
}
}

使用Hashset比较简单.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
break;
}
if (fast == null || fast.next == null) {
return null;
}
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}

Floyd’s Tortoise and Hare
时间复杂度: O(n)
空间复杂度: O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null)
return null;
ListNode slow = head, fast = head;
do {
slow = slow.next;
fast = fast.next.next;
} while (fast != null && fast.next != null && slow != fast);

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

看那个do while, 本来我写的是while循环, 用的这个条件, 发现一开始slow和start出发点一样, 这样这个循环就不会被进入, 也就是还没开始跑就结束了. 于是我想到用do while, 但是这又会牵扯到一个问题就是如果上来fast就是null或者fast.next是null, 因此我又在第一行加了一个head是null或者head.next是null的判断.