797. All Paths From Source to Target
Given a directed acyclic graph (DAG) of n nodes labeled from 0 to n - 1, find all possible paths from node 0 to node n - 1 and return them in any order.
The graph is given as follows: graph[i] is a list of all nodes you can visit from node i (i.e., there is a directed edge from node i to node graph[i][j]).
Example 1:
Input: graph = [[1,2],[3],[3],[]]
Output: [[0,1,3],[0,2,3]]
Explanation: There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3.
Example 2:
Input: graph = [[4,3,1],[3,2,4],[3],[4],[]]
Output: [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
Constraints:
- n == graph.length
- 2 <= n <= 15
- 0 <= graph[i][j] < n
- graph[i][j] != i (i.e., there will be no self-loops).
- All the elements of graph[i] are unique.
- The input graph is guaranteed to be a DAG.
From: LeetCode
Link: 797. All Paths From Source to Target
Solution:
Ideas:
-
DFS traversal is used to explore every path from node 0 to node n-1.
-
A path[] keeps track of the current path.
-
When reaching the last node (n - 1), copy path into the result.
-
result stores all valid paths.
-
returnSize stores the number of paths found.
-
returnColumnSizes records the length of each path.
Code:
#define INITIAL_CAPACITY 128
#define MAX_NODES 15
void dfs(int** graph, int* graphColSize, int node, int* path, int pathLen,
int*** result, int* returnSize, int* capacity, int** returnColumnSizes, int target) {
path[pathLen++] = node;
if (node == target) {
if (*returnSize >= *capacity) {
*capacity *= 2;
*result = realloc(*result, (*capacity) * sizeof(int*));
*returnColumnSizes = realloc(*returnColumnSizes, (*capacity) * sizeof(int));
}
(*result)[*returnSize] = malloc(sizeof(int) * pathLen);
memcpy((*result)[*returnSize], path, sizeof(int) * pathLen);
(*returnColumnSizes)[*returnSize] = pathLen;
(*returnSize)++;
return;
}
for (int i = 0; i < graphColSize[node]; ++i) {
dfs(graph, graphColSize, graph[node][i], path, pathLen,
result, returnSize, capacity, returnColumnSizes, target);
}
}
int** allPathsSourceTarget(int** graph, int graphSize, int* graphColSize,
int* returnSize, int** returnColumnSizes) {
int capacity = INITIAL_CAPACITY;
int** result = malloc(sizeof(int*) * capacity);
*returnColumnSizes = malloc(sizeof(int) * capacity);
*returnSize = 0;
int* path = malloc(sizeof(int) * graphSize); // max path length is graphSize
dfs(graph, graphColSize, 0, path, 0, &result, returnSize, &capacity, returnColumnSizes, graphSize - 1);
free(path);
return result;
}