题目描述
Given a linked list, determine if it has a cycle in it.
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.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.
方法思路
Approach1:Hash Table
Complexity analysis
Time complexity : O(n).
We visit each of the nnn elements in the list at most once.
Adding a node to the hash table costs only O(1)time.
Space complexity: O(n).
The space depends on the number of elements added to the hash table,
which contains at most nnn elements.
class Solution{
public boolean hasCycle(ListNode head) {
Set<ListNode> nodesSeen = new HashSet<>();
while (head != null) {
if (nodesSeen.contains(head)) {
return true;
} else {
nodesSeen.add(head);
}
head = head.next;
}
return false;
}
}
什么是HashSet
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。
Approach 2: Two Pointers
Complexity analysis
Time complexity : O(n)
Space complexity : O(1)
class Solution{
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
//针对链表为null或者说只有一个结点的情况
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
//如果是循环链表,则一个指针快,另一个慢,二者终会相等
//如果不是循环链表,则到底部之后,返回 false
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}