Linked List Cycle II
Question
Given a linked list, return the node where the cycle begins. If there is no cycle, return
null
.Note: Do not modify the linked list.
Tag
- Linked List
- Two Pointers
Thought
There are two ways to solve the problem:
- Use a visited set to mark all the visited nodes, once the pointer find a visited node, it is the start node for the cycle.
- Use two pointer algorithm. There is a mathematical equation within this problem:
Suppose the distance between the encountered node and the start node of the cycle is l1, and the distance between the start node and the head node of the linked list is l2. Then the distance of l1 is equal to l2.
Code
Use set
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# Use set
visited = set()
ptr = head
while ptr is not None:
if ptr in visited:
return ptr
else:
visited.add(ptr)
ptr = ptr.next
return None
Use two pointers
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# Use two pointers
if head is None or head.next is None:
return None
fast, slow = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
if slow == fast:
slow = head
while slow != fast:
fast = fast.next
slow = slow.next
return fast
return None