2026-08-25 19:14:07 -06:00

2.8 KiB

layout, title, last_solved, category, leetcode_url, status
layout title last_solved category leetcode_url status
page Linked List Cycle II 2020-06-25 linked list, cycle detection https://leetcode.com/problems/linked-list-cycle-ii Solved

Problem

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

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.

Note: Do not modify the linked list.

 

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
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: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.


Example 3:

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

Solution

Here's the correct algorithm (similiar to Find the Duplicate Number). However, since we're dealing with linked lists, we have to do error checks.

{% highlight python %}

def detectCycle(self, head: ListNode) -> ListNode:

slow = head
fast = head

# find intersection in cycle
while True:
    slow = slow.next
    fast = fast.next.next
    
    if slow is fast:
        break


# reset slow back to head and find entrance
# the gap between the beginning and entrance == gap between fast and entrance
# (this only applies if fast moved 2x as fast as slow)
slow = head
while slow!=fast:
    slow = slow.next
    fast = fast.next

return slow

{% endhighlight %}


After adding null checks and followed the tips from Linked List Cycle I

This one we need to start both slow and fast at head. fast cannot be head.next because where fast ends needs to be equidistance to the entrance.

{% highlight python %}

def detectCycle(self, head: ListNode) -> ListNode:

if not head: return None

slow = head
fast = head

# find intersection in cycle
while True:
    
    if slow is None or fast is None or fast.next is None:
        return None
    
    slow = slow.next
    fast = fast.next.next
    
    if slow is fast:
        break


# reset slow back to head and find entrance
# the gap between the beginning and entrance == gap between fast and entrance
# (this only applies if fast moved 2x as fast as slow)
slow = head
while slow!=fast:
    slow = slow.next
    fast = fast.next

return slow

{% endhighlight %}

image1