Skip to content

Commit 79999ba

Browse files
committed
Fix is_list_cyclic
1 parent b736406 commit 79999ba

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

epi_judge_python/is_list_cyclic.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,53 @@
88

99

1010
def has_cycle(head: ListNode) -> Optional[ListNode]:
11-
# TODO - you fill in here.
11+
"""Return None if there is no cycle, or the node at the start
12+
of the cycle if there is a cycle."""
13+
14+
# If list has only 1 element, no cycle.
15+
if not head:
16+
return None
17+
if not head.next:
18+
return None
19+
20+
# Slow and fast node.
21+
slow, fast = head, head
22+
i = 0
23+
while fast.next and fast.next.next:
24+
# Move fast up every round.
25+
fast = fast.next
26+
# Move slow up every other round.
27+
if i % 2:
28+
slow = slow.next
29+
30+
# Detect cycle
31+
if fast is slow or fast.next is slow:
32+
# We have a cycle!
33+
# We can count the length of the cycle in O(n) time by
34+
# freezing slow and moving fast until it hits slow again.
35+
fast = slow.next
36+
cycle_length = 1
37+
while fast is not slow:
38+
fast = fast.next
39+
cycle_length += 1
40+
print(cycle_length)
41+
42+
# Now that we have cycle length, we just start fast and slow at head.
43+
# increment slow after incrementing fast cycle_length times. once
44+
# fast is slow, slow is the start of the cycle.
45+
fast, slow = head, head
46+
for _ in range(cycle_length):
47+
fast = fast.next
48+
49+
while fast is not slow:
50+
fast = fast.next
51+
slow = slow.next
52+
53+
return slow
54+
55+
i += 1
56+
57+
# If we reach the end (fast.next is None).
1258
return None
1359

1460

@@ -42,6 +88,10 @@ def has_cycle_wrapper(executor, head, cycle_idx):
4288
if result is None:
4389
raise TestFailure('Existing cycle was not found')
4490
cursor = result
91+
if result.data != cycle_idx:
92+
raise TestFailure(
93+
f"Returned node {result.data} is not the start of the cycle {cycle_idx}"
94+
)
4595
while True:
4696
cursor = cursor.next
4797
cycle_length -= 1

0 commit comments

Comments
 (0)