Enumerate All Simple Directed Cycles
Company: ByteDance
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Given a directed graph as an adjacency list, return every distinct simple directed cycle.
For this practice version, a simple directed cycle follows directed edges back to its starting vertex without repeating any other vertex. Represent a cycle as an array of its vertices without repeating the starting vertex at the end. The last vertex must have an edge to the first. A self-loop is a one-vertex cycle.
### Input
- `graph`: an array of adjacency lists. Vertices are labeled `0` through `graph.length - 1`; `graph[u]` lists the vertices reachable by one directed edge from `u`.
### Output
Return the cycles in canonical form:
- Rotate each cycle so its smallest vertex label appears first.
- List each such cycle once. Rotations of a sequence represent the same cycle.
- Preserve edge direction. Reversing a sequence does not generally represent the same directed cycle.
- Sort the resulting arrays lexicographically by their vertex sequences, using the shorter sequence first when one is a prefix of another.
### Constraints and Edge Cases
- For this practice version, `1 <= graph.length <= 8`.
- Adjacency lists may be unsorted but contain no repeated neighbors.
- The graph may be disconnected and may contain self-loops.
- If the graph contains no directed cycles, return an empty array.
### Example 1
```text
graph = [[1], [2], [0,1], []]
output = [[0,1,2], [1,2]]
```
The cycles `[1,2,0]` and `[2,0,1]` are rotations of `[0,1,2]`, so they are not additional results.
### Example 2
```text
graph = [[0,1,2], [0,2], [0,1]]
output = [[0], [0,1], [0,1,2], [0,2], [0,2,1], [1,2]]
```
Both `[0,1,2]` and `[0,2,1]` are valid because their directed edges exist, and they are distinct. The self-loop contributes `[0]`.
Overview: Enumerate distinct simple directed cycles using a canonical representation that handles rotations, opposite directions, and self-loops.
Read the full ByteDance Software Engineer interview experience this question came from
Given a directed graph as an adjacency list, return every distinct simple directed cycle.
For this practice version, a simple directed cycle follows directed edges back to its starting vertex without repeating any other vertex. Represent a cycle as an array of its vertices without repeating the starting vertex at the end. The last vertex must have an edge to the first. A self-loop is a one-vertex cycle.
### Input
- `graph`: an array of adjacency lists. Vertices are labeled `0` through `graph.length - 1`; `graph[u]` lists the vertices reachable by one directed edge from `u`.
### Output
Return the cycles in canonical form:
- Rotate each cycle so its smallest vertex label appears first.
- List each such cycle once. Rotations of a sequence represent the same cycle.
- Preserve edge direction. Reversing a sequence does not generally represent the same directed cycle.
- Sort the resulting arrays lexicographically by their vertex sequences, using the shorter sequence first when one is a prefix of another.
### Constraints and Edge Cases
- For this practice version, `1 <= graph.length <= 8`.
- Adjacency lists may be unsorted but contain no repeated neighbors.
- The graph may be disconnected and may contain self-loops.
- If the graph contains no directed cycles, return an empty array.
### Example 1
```text
graph = [[1], [2], [0,1], []]
output = [[0,1,2], [1,2]]
```
The cycles `[1,2,0]` and `[2,0,1]` are rotations of `[0,1,2]`, so they are not additional results.
### Example 2
```text
graph = [[0,1,2], [0,2], [0,1]]
output = [[0], [0,1], [0,1,2], [0,2], [0,2,1], [1,2]]
```
Both `[0,1,2]` and `[0,2,1]` are valid because their directed edges exist, and they are distinct. The self-loop contributes `[0]`.
Constraints
- 1 <= graph.length <= 8; vertices are labeled 0 through graph.length-1 and all neighbors are valid labels.
- Adjacency lists may be unsorted but contain no repeated neighbor; disconnected graphs and self-loops are allowed.
- A simple cycle follows directed edges back to its start and repeats no other vertex; do not repeat the closing start in its returned array.
- Rotate each cycle to its minimum label, emit it once, retain distinct directed orientations, and sort the arrays in numeric lexicographic order with shorter proper prefixes first.
- A self-loop contributes a singleton array. Return an empty array when no cycles exist.
Examples
Input: ([[1], [2], [0, 1], []],)
Expected Output: [[0, 1, 2], [1, 2]]
Explanation: Published sample 1: the three-vertex cycle and the 1-to-2 cycle are the only canonical cycles.
Input: ([[0, 1, 2], [0, 2], [0, 1]],)
Expected Output: [[0], [0, 1], [0, 1, 2], [0, 2], [0, 2, 1], [1, 2]]
Explanation: Published sample 2: preserve the self-loop, all three pairs and both directed triangle orientations.