-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path141_LinkedListCycle.py
148 lines (118 loc) · 4.23 KB
/
141_LinkedListCycle.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
# By Will Shin
#
#-------------------------------------------------------------------------------
# LeetCode prompt
#-------------------------------------------------------------------------------
"""
Given a linked list, determine if it has a cycle in it.
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.
"""
#-------------------------------------------------------------------------------
# Approach
#-------------------------------------------------------------------------------
"""
- So there are 2 classical ways to approach this problem
1. This is to use a HashTable.
- For each node that is in the list, you add it to a hashmap
- you check to see if it is in the hashmap O(1) operation
- and you are going through the linked list once O(n)
- so this is pretty efficient, but you need O(n) space.
2. You can also use 2 pointers. In this way you are using O(1) additional space (just one more node)
- you are having 2 pointers.
- one "fast" one
- one "slow" one
- if they ever meet, then you have a looop
- how do you go about checking this
- I can even implement both
- Now to get the implementation of this. That is going to be the tricky part, and that is what I'll try to do this afternoon.
-
"""
#-------------------------------------------------------------------------------
# Soluton
#-------------------------------------------------------------------------------
def my_hasCycle_FastSlowPointers(head):
# if we are the end node, then we return False, there is no loop
if head is None or head.next is None:
return False
slow_pointer = head
fast_pointer = head.next
while slow_pointer != fast_pointer:
# we have gotten to the end
if fast_pointer is None or fast_pointer.next is None:
return False
slow_pointer = slow_pointer.next
fast_pointer = fast_pointer.next.next
return True
def my_hasCycle_hashmap(head):
seen = {}
while head is not None:
if head in seen.keys():
return True
else:
seen[head] = 1
# keep going
head = head.next
return False
# this is my driver for
def my_hasCycle(head):
#return my_hasCycle_hashmap(head)
return my_hasCycle_FastSlowPointers(head)
#-------------------------------------------------------------------------------
# Main Leetcode Input Driver
#-------------------------------------------------------------------------------
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
return my_hasCycle(head)
#-------------------------------------------------------------------------------
# Unit Test
#-------------------------------------------------------------------------------
# build first loop
def build_test1():
vals = [3, 2, 0, -4]
node0 = ListNode(vals[0])
node1 = ListNode(vals[1])
node2 = ListNode(vals[2])
node3 = ListNode(vals[3])
node0.next = node1
node1.next = node2
node2.next = node3
node3.next = node0
return node0
def build_test2():
vals = [1, 2]
node0 = ListNode(vals[0])
node1 = ListNode(vals[1])
node0.next = node1
node1.next = node0
return node0
def build_test3():
vals = [1]
node0 = ListNode(vals[0])
return node0
import unittest
class TestSolution(unittest.TestCase):
def test_1(self):
nodes = build_test1()
res = True
self.assertEqual(Solution().hasCycle(nodes), res)
def test_2(self):
nodes = build_test2()
res = True
self.assertEqual(Solution().hasCycle(nodes), res)
def test_3(self):
nodes = build_test3()
res = False
self.assertEqual(Solution().hasCycle(nodes), res)
unittest.main()