Advertisement

Longest Cycle in a Graph - LeetCode 2360 Solution

Longest Cycle in a Graph - Complete Solution Guide

Longest Cycle in a Graph is LeetCode problem 2360, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

You are given a directed graph of n nodes numbered from 0 to n - 1 , where each node has at most one outgoing edge. The graph is represented with a given 0-indexed array edges of size n , indicating that there is a directed edge from node i to node edges[i] . If there is no outgoing edge from node i , then edges[i] == -1 . Return the length of the longest cycle in the graph . If no cycle exists, return -1 . A cycle is a path that starts and ends at the same node. Example 1: Input: edges = [3,3,4

Detailed Explanation

The problem asks us to find the longest cycle in a directed graph. The graph is represented by an array `edges` where `edges[i]` indicates the node to which node `i` points. If `edges[i]` is -1, then node `i` has no outgoing edge. We need to find the length of the longest cycle in this graph. A cycle is a path that starts and ends at the same node. If there are no cycles, we should return -1. The constraints are that the number of nodes (n) is between 2 and 10^5, and each node has at most one outgoing edge.

Solution Approach

The solution uses a modified Depth-First Search (DFS) approach to traverse the graph and detect cycles. It iterates through each node in the graph. If a node hasn't been visited yet, it starts a DFS traversal from that node. During the traversal, it maintains a 'path_map' (HashMap/unordered_map) to store the distance of each node from the starting node in the current path. If a node is encountered that is already present in the 'path_map', it means a cycle has been detected. The length of the cycle is calculated as the difference between the current distance and the distance of the node in the 'path_map'. The maximum cycle length is updated accordingly. After each DFS traversal, all nodes in the current 'path_map' are marked as visited to avoid re-exploring them in subsequent iterations.

Step-by-Step Algorithm

  1. Step 1: Initialize an array 'visited' of boolean values, all set to 'false'. This array will keep track of globally visited nodes.
  2. Step 2: Initialize 'longest_cycle' to -1. This variable will store the length of the longest cycle found so far.
  3. Step 3: Iterate through each node 'i' from 0 to n-1.
  4. Step 4: If 'visited[i]' is 'false', start a DFS traversal from node 'i'.
  5. Step 5: Inside the DFS traversal, create a 'path_map' (dictionary/hashmap) to store the distance of each node from the starting node 'i' in the current path.
  6. Step 6: Initialize 'dist' to 0, representing the current distance from the starting node.
  7. Step 7: Initialize 'curr' to 'i', representing the current node being visited.
  8. Step 8: While 'curr' is not -1 and 'visited[curr]' is 'false', do the following:
  9. Step 9: If 'curr' is already present in 'path_map', calculate the cycle length as 'dist - path_map[curr]' and update 'longest_cycle' with the maximum value. Break the inner loop (cycle detected).
  10. Step 10: If 'curr' is not in 'path_map', add it to 'path_map' with its distance 'dist'.
  11. Step 11: Increment 'dist' by 1.
  12. Step 12: Move to the next node by setting 'curr' to 'edges[curr]'.
  13. Step 13: After the DFS traversal is complete (inner loop terminates), mark all nodes present in 'path_map' as visited by setting 'visited[node]' to 'true' for each node in 'path_map'.
  14. Step 14: After iterating through all nodes, return 'longest_cycle'.

Key Insights

  • Insight 1: The graph is a directed graph where each node has at most one outgoing edge. This means each connected component of the graph resembles a 'linked list' with a possible 'cycle' at its end.
  • Insight 2: We can use Depth-First Search (DFS) to traverse the graph and detect cycles. We need to keep track of the distance from the starting node during the traversal to calculate the cycle length if we encounter a node already visited in the current path.
  • Insight 3: To avoid re-processing parts of the graph, we can use a 'visited' array to mark nodes that have been fully explored. Once a path is fully processed, its nodes will be globally 'visited' and won't be explored again.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(n)

Topics

This problem involves: Depth-First Search, Breadth-First Search, Graph, Topological Sort.

Companies

Asked at: Juspay.