forked from UTSAVS26/PyVerse
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UTSAVS26#897 cycle detection in linked list
Given the `head` of a linked list, determine if the linked list contains a cycle. A cycle exists if a node in the list points back to an earlier node, creating a loop in the list. Internally, a variable `pos` represents the index of the node that the tail's `next` pointer is connected to. If there is no cycle, `pos` is `-1`.
- Loading branch information
Showing
2 changed files
with
90 additions
and
0 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
Algorithms_and_Data_Structures/Linked List/Detect_Cycle_in_List/program.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
class ListNode: | ||
def __init__(self, x): | ||
self.val = x | ||
self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: ListNode) -> bool: | ||
slow, fast = head, head | ||
|
||
# Use Floyd's Cycle-Finding Algorithm | ||
while fast and fast.next: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
return True | ||
return False | ||
|
||
# Helper function to create a linked list with a cycle | ||
def createLinkedList(values, pos): | ||
head = ListNode(values[0]) | ||
current = head | ||
nodes = [head] # store nodes to connect cycle later | ||
|
||
for value in values[1:]: | ||
new_node = ListNode(value) | ||
current.next = new_node | ||
current = new_node | ||
nodes.append(new_node) | ||
|
||
# Create cycle if pos is not -1 | ||
if pos != -1: | ||
current.next = nodes[pos] | ||
|
||
return head | ||
|
||
# Helper function to display the result | ||
def printResult(head, pos): | ||
solution = Solution() | ||
has_cycle = solution.hasCycle(head) | ||
print(f"Cycle at position {pos}: {'Cycle detected' if has_cycle else 'No cycle detected'}") | ||
|
||
# Example usage | ||
values = [3, 2, 0, -4] | ||
pos = 1 # means the last node connects to the node at index 1 | ||
head = createLinkedList(values, pos) | ||
print("Input linked list values:", values) | ||
printResult(head, pos) | ||
|
||
# Test with no cycle | ||
values_no_cycle = [1, 2] | ||
pos_no_cycle = -1 # no cycle | ||
head_no_cycle = createLinkedList(values_no_cycle, pos_no_cycle) | ||
print("\nInput linked list values:", values_no_cycle) | ||
printResult(head_no_cycle, pos_no_cycle) |
36 changes: 36 additions & 0 deletions
36
Algorithms_and_Data_Structures/Linked List/Detect_Cycle_in_List/readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Linked List Cycle Detection | ||
|
||
## Problem Statement | ||
Given the `head` of a linked list, determine if the linked list contains a cycle. A cycle exists if a node in the list points back to an earlier node, creating a loop in the list. Internally, a variable `pos` represents the index of the node that the tail's `next` pointer is connected to. If there is no cycle, `pos` is `-1`. | ||
|
||
Return `true` if the linked list has a cycle, otherwise return `false`. | ||
|
||
### Example | ||
|
||
Given the linked list: | ||
|
||
- **Input**: `head = [3,2,0,-4], pos = 1` | ||
- **Output**: `true` | ||
|
||
### Constraints | ||
- The number of nodes in the list is in the range `[0, 10^4]`. | ||
- `-10^5 <= Node.val <= 10^5` | ||
- `pos` is `-1` if there is no cycle. | ||
|
||
## Solution Approach | ||
|
||
### Floyd’s Cycle Detection Algorithm (Tortoise and Hare) | ||
This approach uses two pointers (`slow` and `fast`) to detect a cycle: | ||
|
||
1. **Initialize**: | ||
- Set `slow` and `fast` to `head`. | ||
|
||
2. **Traverse**: | ||
- Move `slow` by one step (`slow = slow->next`) and `fast` by two steps (`fast = fast->next->next`) in each iteration. | ||
|
||
3. **Cycle Check**: | ||
- If there’s a cycle, `slow` and `fast` will eventually meet at some point within the loop. | ||
- If `fast` reaches the end (`NULL`), there is no cycle. | ||
|
||
This algorithm efficiently checks for cycles in `O(n)` time complexity with `O(1)` space complexity. | ||
|