-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinked-list-cycle.py
executable file
·75 lines (60 loc) · 1.99 KB
/
linked-list-cycle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# -*- coding: utf-8 -*-
"""
Created on Tue Feb 4 23:03:03 2020
@author: johnoyegbite
"""
# SOLVED!
"""
Problem:
Given a linked list, determine if it has a cycle in it.
Example 1:
Input: 21->10->4->5, then tail connects to node index 1(value 10).
Output: true
Example 2:
Input: 21->10->4->5->null
Output: false
Challenge:
Follow up:
Can you solve it without using extra space?
"""
"""
Intuition:
Imagine two runners running on a track at different speed.
What happens when the track is actually a circle?
Algorithm:
The space complexity can be reduced to O(1)O(1) by considering two pointers
at different speed - a slow pointer and a fast pointer.
The slow pointer moves one step at a time while the fast pointer moves two
steps at a time.
If there is no cycle in the list, the fast pointer will eventually reach
the end and we can return false in this case.
Now consider a cyclic list and imagine the slow and fast pointers are two
runners racing around a circle track. The fast runner will eventually meet
the slow runner. Why?
Consider this case (we name it case A) - The fast runner is just one step
behind the slow runner. In the next iteration, they both increment one and
two steps respectively and meet each other.
"""
"""
Definition of ListNode
"""
class ListNode(object):
def __init__(self, val, next=None):
self.val = val
self.next = next
"""
@param head: The first node of linked list.
@return: True if it has a cycle, or false
"""
def hasCycle(head):
# write your code here
if not head:
return False
slow = head
fast = head.next
while slow != fast: # while fast has not catched up with slow
if not fast or not fast.next:
return False
slow = slow.next # move one step at a time
fast = fast.next.next # move two steps at a time
return True