/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funcdetectCycle(head *ListNode) *ListNode { m :=make(map[*ListNode]bool)for head !=nil {if _,found := m[head]; found {return head } m[head] =true head = head.Next }returnnil}
Solution 2 (Go)
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funcdetectCycle(head *ListNode) *ListNode { hasCycle, tortoise :=hasCycle(head)if head ==nil|| head.Next ==nil||!hasCycle {returnnil } hare := head// both move by 1 and look for second meetfor tortoise != hare { tortoise = tortoise.Next hare = hare.Next }return tortoise}// from ID: 141funchasCycle(head *ListNode) (bool, *ListNode) { tortoise, hare := head, headfor tortoise !=nil&& hare !=nil&& hare.Next !=nil { tortoise = tortoise.Next hare = hare.Next.Nextif tortoise == hare {returntrue, tortoise } }returnfalse, nil}
Solution 3 (Java)
/** * Definition for ListNode * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */publicclassSolution { /** * @param head: The first node of linked list. * @return: The node where the cycle begins. if there is no cycle, return null */publicListNodedetectCycle(ListNode head) {if (head ==null||head.next==null)returnnull;ListNode slow = head;ListNode fast =head.next;// slow and fast meet for the first timewhile (slow != fast) {if (fast ==null||fast.next==null)returnnull; slow =slow.next; fast =fast.next.next; }// the second meeting point is the start of the cycle fast =fast.next;while (head != fast) { head =head.next; fast =fast.next; }return head; }}
We first use the same algorithm (modified to return the first meeting point) for problem ID: 141. If there is no cycle, we are done and return null. If there is a cycle, we store the first meeting point. From this first meeting point, we set the speed of both the tortoise and the hare to moving by 1 each time. Eventually, they will meet again at the start of the cycle. A quick proof is as follows:
Let x be the distance between the head and the start of the cycle, y be the distance between the start of the cycle to the first meeting point, z be the distance between the first meeting point to the start of the cycle. It is clear that y + z = n, where n is the length of the cycle. Consider the following equations for their first meet:
ttortoise=1x+y,thare=2x+y+z+y
Because they meet at the first meeting point, their time spent traveling should be the same. Setting the two t's equal to each other, we have x = z.
Using this result, we have either one of them start at the head of the list and the other continue at their first meeting point (with the same speed now). They will eventually meet at the start of the cycle thanks to the fact x = z.