# Solution 1
def hasCycle(head: Optional[ListNode]) -> bool:
# define the two heads
slow, fast = head, head
# while on the fast head as if there is no loop it will end first
while fast:
slow = slow.next
fast = fast.next
# if not at the end, fast head move to times faster than slow head
if fast:
fast = fast.next
# if they meet return True
if slow==fast:
return True
# if we reach the end hence there is no loop (otherwise heads would loop forever)
return(False)
# Solution 2
def hasCycle(head: Optional[ListNode]) -> bool:
d = {}
while head:
if head in d:
return(True)
d[head] = 0
head = head.next
return(False)