Cycle detection algorithm in Scala

admin

12/13/2024
All Articles

#Cycle detection algorithm in Scala

Cycle detection algorithm in Scala

Cycle detection algorithm in Scala

In computer science, detecting a cycle in a linked list is a classic problem. Cycles in linked lists can cause infinite loops in your code and lead to memory inefficiency. Today, we'll discuss how to detect a cycle in a linked list using Scala with the help of the two-pointer technique.
 
Below is a Scala implementation to solve the problem:
The Code
 
object Solution {
    def hasCycle(head: ListNode): Boolean = 
    {
      var p1 = head
      var p2 = head.next
      val x = true
 
      while (p1 != p2) {
        if (p1 == null || p2 == null) {
          return false
        }
 
        if (p2.next == null) {
          return false
        }
 
        p1 = p1.next
        p2 = p2.next.next
      }
 
      x
    }
}

 

Explanation of the Code

1. Understanding the Two-Pointer Technique
 
The two-pointer technique involves using two pointers:
 
    p1: A slow pointer that moves one step at a time.
    p2: A fast pointer that moves two steps at a time.
 
If there’s a cycle in the linked list, the fast pointer (p2) will eventually meet the slow pointer (p1). If p1 and p2 point to the same node during iteration, it indicates the presence of a cycle.
2. Initialization
 
    p1 is initialized to head, the starting node of the linked list.
    p2 is initialized to head.next, the second node in the list.
 
3. Loop Condition
 
The while (p1 != p2) loop runs as long as the two pointers don’t meet. Inside the loop:
 
    If either p1 or p2 becomes null, it means there’s no cycle, and the function returns false.
    If p2.next is null, it also confirms the absence of a cycle.
 
4. Pointer Movement
 
    p1 moves one step forward (p1 = p1.next).
    p2 moves two steps forward (p2 = p2.next.next).
 
5. Returning Result
 
The variable x is returned after exiting the loop. However, this seems unnecessary, as x is always true. The function could directly return true when the loop exits.
Issues in the Code
 
While the logic is mostly correct, the code has a few issues:
 
    Returning x Always
        The variable x is redundant and not meaningful in this context.
        Instead, the function should return true when the loop exits.
    p2 Initialization
        The initialization of p2 as head.next may cause a NullPointerException if the input list is empty (head == null).
 

Improved Code

Here’s an improved version of the function:
 
object Solution {
    def hasCycle(head: ListNode): Boolean = {
        if (head == null || head.next == null) return false
 
        var p1 = head
        var p2 = head.next
 
        while (p1 != p2) {
            if (p1 == null || p2 == null || p2.next == null) {
                return false
            }
            p1 = p1.next
            p2 = p2.next.next
        }
 
        true // A cycle is detected
    }
}
 
Key Improvements
 
    Initial Null Check: The code checks whether the list is empty or has only one node before proceeding.
    Simplified Return: It directly returns true when a cycle is detected.
 
Example Usage
 
Here’s how you might test this function:
 
// Define the ListNode class
class ListNode(var value: Int = 0, var next: ListNode = null)
 
// Create a linked list with a cycle
val node1 = new ListNode(1)
val node2 = new ListNode(2)
val node3 = new ListNode(3)
node1.next = node2
node2.next = node3
node3.next = node1 // Cycle created
 
println(Solution.hasCycle(node1)) // Output: true
 
// Create a linked list without a cycle
val node4 = new ListNode(4)
val node5 = new ListNode(5)
node4.next = node5
 
println(Solution.hasCycle(node4)) // Output: false
 

Conclusion

 
Detecting a cycle in a linked list is an essential skill for working with data structures. Using the two-pointer technique is an efficient way to solve this problem in O(n) time complexity and O(1) space complexity.
 
For more articles on Scala programming and advanced algorithms, stay tuned to orientalguru.co.in!