All Paths From Source to Target

medium graph dfs backtracking

Problem

Given a directed acyclic graph of n nodes (0 to n − 1) as adjacency lists, return all possible paths from node 0 to node n − 1 in any order.

Inputgraph = [[1,2],[3],[3],[]]
Output[[0,1,3],[0,2,3]]
Two routes from node 0 to node 3.

def all_paths_source_target(graph):
    n = len(graph)
    out = []
    path = [0]
    def dfs(u):
        if u == n - 1:
            out.append(path[:])
            return
        for v in graph[u]:
            path.append(v)
            dfs(v)
            path.pop()
    dfs(0)
    return out
function allPathsSourceTarget(graph) {
  const n = graph.length;
  const out = [];
  const path = [0];
  const dfs = (u) => {
    if (u === n - 1) { out.push(path.slice()); return; }
    for (const v of graph[u]) {
      path.push(v);
      dfs(v);
      path.pop();
    }
  };
  dfs(0);
  return out;
}
class Solution {
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        int n = graph.length;
        List<List<Integer>> out = new ArrayList<>();
        Deque<Integer> path = new ArrayDeque<>();
        path.push(0);
        dfs(graph, 0, n - 1, path, out);
        return out;
    }
    private void dfs(int[][] g, int u, int target, Deque<Integer> path, List<List<Integer>> out) {
        if (u == target) {
            List<Integer> copy = new ArrayList<>(path);
            Collections.reverse(copy);
            out.add(copy);
            return;
        }
        for (int v : g[u]) {
            path.push(v);
            dfs(g, v, target, path, out);
            path.pop();
        }
    }
}
class Solution {
public:
    vector<vector<int>> out;
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        int n = graph.size();
        vector<int> path = {0};
        dfs(graph, 0, n - 1, path);
        return out;
    }
    void dfs(vector<vector<int>>& g, int u, int target, vector<int>& path) {
        if (u == target) { out.push_back(path); return; }
        for (int v : g[u]) {
            path.push_back(v);
            dfs(g, v, target, path);
            path.pop_back();
        }
    }
};
Time: O(2ⁿ · n) Space: O(n)