Problem
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.
Author's note
I’m not sure how pos is related to the problem itself but it teaches us how to represent a cycle in future coding practice.
Idea 1: Hash Table
The idea is very clear. We check every node and see we have seen this node before, if not, save into the hash table and check the next node.
HashSet vs. HashMap
Why do we choose a HashSet instead of a HashMap?
HashSet is a set, e.g. {1, 2, 3, 4, 5},
HashMap is a key -> value pair map, e.g. {a -> 1, b -> 2, c -> 2, d -> 1}
Since we only need to save one node (actually it’s the address of the node) instead of a key-value pair, we’d like to choose a HashSet instead of a HashMap.
HashSet
There are 3 commands that we should know to solve this problem.
Create: Set<ListNode> seen = new HashSet<ListNode>();
Check if X is contained in a HashSet: seen.contains(X) // true or false
Add X to a HashSet: seen.add(X)
Code
// Hash Table
public class Solution {
public boolean hasCycle(ListNode head) {
// Create a hashtable
Set<ListNode> seen = new HashSet<ListNode>();
// We check every node and see we have seen this node before,
// if not, save into the hash table and check the next node.
while (head != null) {
if (seen.contains(head)) return true;
else seen.add(head);
head = head.next;
}
return false;
}
}
复制代码
Idea 2: 2 pointers
We can use 2 pointers with different speed and check if they meet. So we need to design their speed careful so that they don’t miss each other, like this:
Creating a pointer slow who walks 1 step each time
Creating a pointer fast who walks 2 steps each time.
In this way they will finally meet. “Leetcode - solutions” explains this part very well.
Code
// 2 pointers
public class Solution {
public boolean hasCycle(ListNode head) {
// Since we're using the value of head and head.next to initialize pointers,
// we need to make sure that they are not null.
if (head == null || head.next == null) return false;
// Set up 2 pointers
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || slow == null) return false;
fast = fast.next.next; // fast.next.next is different with head.next.next in #206(recursive) since here fast.next.next doesn't change it's value while head.next.next in #206(recursive) is assigned to a new value so that it's pointing back.
查到了说:
Return Value: The function returns True if the element is not present in the HashSet otherwise False if the element is already present in the HashSet.
原来.add()还有return value!