All Paths From Source to Target
Given a directed acyclic graph (DAG) with n nodes labeled from 0 to n-1, find all possible paths from node 0 to node n-1. The graph is given as an adjacency list where graph[i] is the list of nodes that node i has an outgoing edge to.
The answer is a list of paths, and each path is a list of node labels starting with 0 and ending with n-1. The order of paths in the answer does not matter, but every distinct route must be included exactly once.
For example, with graph = [[4,3,1],[3,2,4],[3],[4],[]], the answer is [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]. Each path follows directed edges from 0 to 4. With graph = [[1],[]], the only path is [0,1]. With graph = [[]] (a single node), the start equals the target, so the answer is [[0]].
Because the graph is acyclic, there are no cycles to worry about, so a simple depth-first traversal that records the current path is enough. You never need to track a visited set — the absence of cycles guarantees the recursion terminates.
This problem appears in routing, dependency analysis, and circuit design where you must enumerate every way to reach a target. It is a classic introduction to DFS with backtracking and to path enumeration in graphs.
Edge cases include a single-node graph (the answer is [[0]]), a graph with no paths to the target (return an empty list), and dense graphs where the number of paths grows exponentially with n.
Example Input & Output
Multiple paths
Single path
Two paths different routes
Start is target
Two paths
Algorithm Flow
Solution Approach
Use depth-first search with backtracking. Start from node 0, append it to the current path, and explore each neighbor recursively. When the current node equals the target (n-1), copy the path into the result. After exploring a node, remove it from the path so sibling branches are not polluted.
The path.slice() makes a copy before storing it in the result, because path is mutated by backtracking. The final path.pop() undoes the current choice so the recursion can explore sibling branches correctly.
Time complexity is O(number of paths), space complexity is O(n) for the recursion stack and current path.
Best Answers
import java.util.*;
class Solution {
public String solution(int[][] g){
List<String> r=new ArrayList<>();dfs(0,g,new ArrayList<>(),r,g.length);
return String.join(",",r);
}
void dfs(int u,int[][] g,List<Integer> p,List<String> r,int n){
p.add(u);if(u==n-1){StringBuilder sb=new StringBuilder();for(int x:p){if(sb.length()>0)sb.append(",");sb.append(x);}r.add(sb.toString());}
else for(int v:g[u])dfs(v,g,p,r,n);
p.remove(p.size()-1);
}
}Comments (0)
Join the Discussion
Share your thoughts, ask questions, or help others with this Challenge.
