-
Notifications
You must be signed in to change notification settings - Fork 2
feat(data-structures, linked-lists, remove cycle): utilities to detect and remove cycles #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(data-structures, linked-lists, remove cycle): utilities to detect and remove cycles #159
Conversation
…t and remove cycles
📝 WalkthroughWalkthroughCycle-detection and manipulation logic was moved from LinkedList methods into new standalone utilities in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@datastructures/linked_lists/linked_list_utils.py`:
- Around line 44-50: The cycle-detection block uses slow_pointer, fast_pointer
and an optional func but when a cycle is found and func is provided the function
calls func(...) then falls through to return False, contradicting the docstring;
update the code in that branch so after calling func(slow_pointer, fast_pointer)
the function returns True (i.e., ensure both the func and non-func paths return
True when slow_pointer is fast_pointer) so the function consistently reports a
detected cycle.
- Around line 71-77: The cycle-detection loop mixes identity and equality
comparisons: the initial check uses "is" (slow_pointer is fast_pointer) but the
loop uses "!=" which invokes Node.__eq__ (compares keys) and can mis-detect
cycles when distinct nodes have equal keys; update the loop condition to use
identity ("is not") so both comparisons use identity semantics (referencing
slow_pointer and fast_pointer in the function containing the loop) to correctly
count the cycle length.
- Line 132: Change the node comparison in the loop to use identity comparison:
in the while loop that currently checks "while current.next != fixed_pointer"
(variables current and fixed_pointer), replace the inequality operator with an
identity check so it reads as "while current.next is not fixed_pointer"; this
ensures consistent node identity comparison with other functions that use "is" /
"is not".
- Line 39: The tuple unpacking "fast_pointer, slow_pointer = head" is invalid
because head is a single Node; replace it by assigning both pointers to the head
node (set fast_pointer and slow_pointer to head) so both start at the list head;
update the initialization in linked_list_utils.py where fast_pointer,
slow_pointer and head are referenced to use individual assignments (e.g., set
fast_pointer = head and slow_pointer = head) so subsequent logic in functions
using fast_pointer and slow_pointer works correctly.
- Around line 99-105: Replace equality checks with identity checks in the
cycle-detection logic: where the code compares slow_pointer and fast_pointer
(currently using ==) and where it compares current and slow_pointer (currently
using !=), use "is" and "is not" respectively so comparisons use object identity
rather than Node.__eq__ (which compares keys); update the comparisons in the
function containing slow_pointer, fast_pointer, current and head to use "is" /
"is not" so distinct nodes with equal keys are not treated as the same node.
🧹 Nitpick comments (2)
datastructures/linked_lists/linked_list_utils.py (1)
27-27: Unnecessary f-string prefix on docstring.The docstring uses
f"""but contains no interpolated expressions. Use a regular docstring instead.♻️ Proposed fix
- f""" + """datastructures/linked_lists/__init__.py (1)
412-415: Guard clause is redundant with utility function behavior.The check on lines 412-413 is unnecessary because
remove_cyclein the utility already handles these cases viadetect_node_with_cyclereturningNoneand then returninghead. Consider removing for consistency with other delegating methods.♻️ Proposed simplification
def remove_cycle(self) -> Optional[Node]: """ Removes cycle if there exists. This will use the same concept as has_cycle method to check if there is a loop and remove the cycle Returns: Node: head node with cycle removed """ - if not self.head or not self.head.next: - return self.head - return remove_cycle(self.head)
… nth node from end
Describe your change:
Detect and remove cycles
Checklist:
Fixes: #{$ISSUE_NO}.Summary by CodeRabbit
New Features
Breaking Changes
✏️ Tip: You can customize this high-level summary in your review settings.