注册一亩三分地论坛,查看更多干货!
您需要 登录 才可以下载或查看附件。没有帐号?注册账号
x
本帖最后由 liuzz10 于 2020-8-26 14:03 编辑
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.
- slow = slow.next;
- }
-
- // Only return true when 2 pointers are the same
- return true;
- }
- }
复制代码
|