Bea.AI coding blog
  • Tree
    • Tree Traverse
    • Iteration based traverse
    • Typical problems and solutions
      • Max width of binary tree
      • Binary Tree & BST Serialize & Deserialize
      • Lowest common ancestor (LCA) for Binary Tree and BST
      • Subproblem-based Approach for Resolving Max Value on Trees
      • Path sum III
  • Graph
  • Data structure
    • Java data structure
  • Algorithm general templates
    • Tree
    • Trie
    • Graph
  • Java Algorithm Tips and Tricks
    • Java concurrent list
  • Coding patterns & Strategies
  • Coding patterns & template
    • 1. Binary Search
    • 2. Two Pointer
    • 3. Sliding Window
    • 4. Backtracking
    • 5. DFS
    • 6. BFS
    • 7. Stack
    • 8. Heap
    • 9. Prefix Sum
    • 10. Linked List
    • 11. BST
    • 12. Line sweep
    • 14. Tree
    • 15. Graph
    • 16. Bit manipulation
    • 17. Matrix
    • 18. Monotonic Stack
    • 19. Sorting
    • 20. Union Find
    • 21. Trie
    • 22. Dynamic programming
    • 23. Customized Data Structure
  • Code interview steps
  • Leetcode
    • Tree
      • Traversal
      • Construction and Conversion
      • Search and Validation
      • Manipulation and Modification
      • Special Trees
      • Miscellaneous
    • Dynamic programing
      • Classic DP Problems
      • Sequence/Array DP
      • Matrix DP
      • Knapsack Problems
      • String DP
      • Tree/Graph DP
      • Optimization Problems
      • Combinatorial DP
    • DFS
      • Graph Traversal
      • Path Finding
      • Tree Traversal
      • Backtracking
      • Topological Sorting
      • Traversal Order
      • Dynamic Programming with DFS
      • Connected Components
    • BFS
      • Graph
      • Tree
      • Matrix
      • String
      • Others
    • Two points
      • Array
      • String
      • Linked List
      • Sorting
      • Others
    • LinkedList
      • Basic Operations
      • Cycle Detection and Handling
      • Intersection and Union
      • Partitioning and Merging
      • Palindrome
      • Miscellaneous
    • Backtracking
    • Binary Search
    • Union Find
    • Trie
    • Sort
    • Heap
    • Randomness
    • Topological sort
    • Stack
    • HashTable
    • Sliding Window
  • Blind 75
    • Array
    • Binary
    • Dynamic Programming
    • Graph
    • Interval
    • LinkedList
    • Matrix
    • String
    • Tree
    • Heap
  • Companies
    • Apple
Powered by GitBook
On this page
  • 6. Linked List Cycle
  • 7. Linked List Cycle II
  • 8. Detect Intersection Point in Y-Linked Lists
  • 9. Find the Duplicate Number
  • 10. Happy Number
  1. Leetcode
  2. LinkedList

Cycle Detection and Handling

PreviousBasic OperationsNextIntersection and Union

Last updated 1 year ago

6. Linked List Cycle

  1. Problem Description: The problem "Linked List Cycle" is a popular problem on LeetCode, and the link to the problem is:

Given a linked list, determine if it has a cycle in it. A cycle is defined as having at least one node in the list point to a previous node in the list.

  1. Optimized Java Code:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        // Initialize two pointers, slow and fast
        ListNode slow = head;
        ListNode fast = head;
        
        // Check if there is a cycle in the list
        while (fast != null && fast.next != null) {
            slow = slow.next;          // Move slow pointer by one step
            fast = fast.next.next;     // Move fast pointer by two steps
            
            // If the slow and fast pointers meet at some point, there is a cycle in the list
            if (slow == fast) {
                return true;
            }
        }
        
        // If we reach here, it means there is no cycle in the list
        return false;
    }
}
  1. Algorithm and Interview Process:

The algorithm used to solve the "Linked List Cycle" problem is called the "Floyd's Cycle Detection Algorithm" or the "Tortoise and Hare Algorithm". It is a classical algorithm to detect cycles in a linked list.

During an interview, the interviewer may ask this problem to test your understanding of linked lists and cycle detection algorithms. Here's how you can approach it:

  • Start by understanding the problem statement and the definition of a cycle in a linked list.

  • Then, analyze the problem and come up with a plan to solve it. The Floyd's Cycle Detection Algorithm is an efficient approach for this problem.

  • Implement the code by initializing two pointers, slow and fast, and move them through the list according to the algorithm.

  • Test your code with various test cases to ensure its correctness.

  • During the interview, explain the algorithm step by step, highlighting the logic behind it and its efficiency compared to other approaches.

  • Discuss the time and space complexity of your solution.

  • Finally, optimize the code as necessary and handle any edge cases that may arise.

Remember to communicate your thoughts and explain your code to the interviewer clearly. It's important to showcase your problem-solving skills and algorithmic thinking during the interview process.

7. Linked List Cycle II

  1. Problem Description: The problem "Linked List Cycle II" is a leetcode medium level problem that asks us to determine if a linked list contains a cycle, and if it does, return the node where the cycle begins. We are given a linked list and we need to return the node from where the cycle starts. If there is no cycle in the linked list, we return null.

Leetcode Problem Link: https://leetcode.com/problems/linked-list-cycle-ii/

  1. Optimized Java Code:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        
        ListNode slow = head;
        ListNode fast = head;
        boolean hasCycle = false;
        
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            
            if (slow == fast) {
                hasCycle = true;
                break;
            }
        }
        
        if (!hasCycle) {
            return null;
        }
        
        slow = head;
        
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        
        return slow;
    }
}
  1. Algorithm and Explanation:

The algorithm to solve this problem uses the concept of "Floyd's cycle-finding algorithm" or "Hare and Tortoise algorithm". The idea is to use two pointers - a slow pointer that moves one step at a time, and a fast pointer that moves two steps at a time. If there is a cycle in the linked list, these two pointers will eventually meet at some point.

Here's how the algorithm works:

  • First, we initialize the slow pointer and the fast pointer to the head of the linked list.

  • Then, we start a loop while the fast pointer is not null and its next pointer is also not null. Within each iteration of the loop, we move the slow pointer one step forward and the fast pointer two steps forward.

  • If the slow pointer and the fast pointer ever meet during this process, it means that the linked list contains a cycle.

  • In that case, we set a flag 'hasCycle' to true and break out of the loop.

  • After the loop, we check the value of the 'hasCycle' flag. If it is false, it means there is no cycle in the linked list and we return null.

  • If the 'hasCycle' flag is true, we reset the slow pointer to the head of the linked list. Now, we start another loop where both the slow pointer and the fast pointer move one step at a time.

  • When the slow pointer and the fast pointer meet again, it means they have reached the node where the cycle starts.

  • Finally, we return the node where the cycle starts.

During the interview process, it is important to mention the algorithm being used and the reasoning behind it. Explaining the Floyd's cycle-finding algorithm and its time complexity (which is O(n)) helps to showcase problem-solving skills and understanding of linked lists.

8. Detect Intersection Point in Y-Linked Lists

  1. Problem Description and Leetcode Link: Detect Intersection Point in Y-Linked Lists Leetcode link: https://leetcode.com/problems/intersection-of-two-linked-lists/

Given the heads of two singly linked lists, which may intersect at some node, return the intersecting node. If the two linked lists do not intersect, return null.

  1. Optimized Java Code for the Problem:

/*
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null)
            return null;
        
        ListNode pA = headA, pB = headB;
        
        // Pointers will meet at intersection point or at null
        while (pA != pB) {
            // After first iteration, pointers will start from the head
            pA = (pA == null) ? headB : pA.next;
            pB = (pB == null) ? headA : pB.next;
        }
        
        return pA;
    }
}
  1. Detailed Description and Algorithm Explanation for the Interview Process:

To solve this problem, we can use a simple two-pointer approach to find the intersection point.

Initially, we set two pointers, pA and pB, to the heads of headA and headB, respectively. We then iterate through the linked lists until either pA or pB reaches the end of the list.

In each iteration, we move pA and pB one step forward. However, if pA reaches the end of the list, we move it to the head of headB. Similarly, if pB reaches the end of the list, we move it to the head of headA.

By doing this, both pA and pB will travel the same distance and reach the intersection point (if it exists) or reach null (if there is no intersection).

This algorithm works because even though the two linked lists may have different lengths, the two pointers will eventually travel the same total distance by the time they reach the intersection or null.

During an interview process, it's important to explain the reasoning behind this algorithm. You can mention that by moving pA and pB one step forward at each iteration, we are essentially canceling out the difference in list lengths. When pA reaches the end of headA, it starts traversing headB, and similarly, pB starts traversing headA when it reaches the end of headB.

By the time both pointers reach the intersection point, they would have traveled the same distance, regardless of the lengths of the two linked lists. This is the key insight of this solution.

Finally, if there is no intersection, both pointers will reach null at the end of the linked lists, indicating that there is no intersection between the two lists.

Overall, this algorithm has a time complexity of O(m + n), where m and n are the lengths of headA and headB respectively, and a space complexity of O(1) as we only use two pointers.

9. Find the Duplicate Number

  1. Problem Description and Leetcode Link: Problem: Find the Duplicate Number Leetcode Link: https://leetcode.com/problems/find-the-duplicate-number/

Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive, prove that at least one duplicate number exists. Assume that there is only one duplicate number, find the duplicate one.

Example: Input: [1,3,4,2,2] Output: 2

  1. Optimized Java Code with Comments:

public class Solution {
    public int findDuplicate(int[] nums) {
        // Use the fast and slow pointer approach to detect if there is a cycle 
        int slow = nums[0];
        int fast = nums[nums[0]];
        
        // Phase 1: Detect the cycle using fast and slow pointers
        // After this loop, the fast and slow pointers will meet inside the cycle
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        
        // Phase 2: Find the start of the cycle
        fast = 0;
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        
        // Return the duplicate number
        return slow;
    }
}
  1. Algorithm and Interview Process Explanation:

This problem can be solved using the fast and slow pointer approach, also known as the Floyd's Tortoise and Hare algorithm. The idea is to consider the array as a linked list, where the value of each element num represents the index of the next element in the array.

To detect if there is a cycle, we can use two pointers: a slow pointer that moves one step at a time, and a fast pointer that moves two steps at a time. If there is a cycle, the fast pointer will eventually catch up to the slow pointer.

In the given problem, since we have a duplicate number, there will definitely be a cycle. So, after detecting the cycle using the fast and slow pointer method, we move the fast pointer back to the beginning of the array and continue with another pointer (slow pointer) to find the start of the cycle.

The start of the cycle is the duplicate number, as the array is guaranteed to have only one duplicate number.

During an interview, you can explain this approach to the interviewer step by step and implement the code together. You can also discuss the time complexity of the solution, which is O(n) since we are traversing the array only twice.

10. Happy Number

  1. Problem Description: The Happy Number problem on LeetCode asks us to determine if a given number is "happy." A happy number is defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.

  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.

LeetCode Problem Link: https://leetcode.com/problems/happy-number/

  1. Optimized Java Code with Detailed Comments:

public class HappyNumber {
    public boolean isHappy(int n) {
        int slow = n; // Initialize slow pointer with the given number
        int fast = n; // Initialize fast pointer with the given number
        
        do {
            slow = getNextNumber(slow); // Move slow pointer one step ahead
            fast = getNextNumber(getNextNumber(fast)); // Move fast pointer two steps ahead
        } while (slow != fast); // Repeat until slow and fast pointers meet
        
        return slow == 1; // Return true if the slow pointer reaches 1, otherwise it implies a cycle
    }
    
    // Helper method to calculate the next number
    private int getNextNumber(int n) {
        int sum = 0;
        while (n > 0) {
            int digit = n % 10; // Get the last digit
            sum += digit * digit; // Add the square of the digit to the sum
            n /= 10; // Remove the last digit
        }
        return sum;
    }
}
  1. Algorithm and Interview Thought Process: The happy number problem can be efficiently solved using the Floyd's Cycle-Finding Algorithm (also known as the Tortoise and the Hare algorithm). This algorithm involves using two pointers - slow and fast - to traverse through the numbers based on the given process.

During an interview, you can approach this problem using the following steps:

Step 1: Understand the problem statement, examples, and constraints. In this case, the given positive integer can be of any size.

Step 2: Define a helper method to calculate the sum of the squares of the digits. This method will be used in the main algorithm to calculate the next number in the sequence.

Step 3: Initialize the slow and fast pointers with the given number.

Step 4: Implement a loop where both pointers move forward. The slow pointer moves one step at a time, while the fast pointer moves two steps at a time.

Step 5: At each step, calculate the next number for both pointers using the helper method.

Step 6: Continue the loop until the slow and fast pointers meet. If they meet, it implies that a cycle is present.

Step 7: Exit the loop and return true if the slow pointer reaches 1. Otherwise, return false as it indicates the presence of a cycle.

By following these steps and explaining your approach with clear comments and code, you can showcase your problem-solving skills and algorithmic thinking during an interview.

Linked List Cycle