题目
标题和出处
标题:所有可能的路径
出处:797. 所有可能的路径
难度
4 级
题目描述
要求
给定一个有 n \texttt{n} n 个结点的有向无环图,结点从 0 \texttt{0} 0 到 n − 1 \texttt{n} - \texttt{1} n−1 编号,找出所有从结点 0 \texttt{0} 0 到结点 n − 1 \texttt{n} - \texttt{1} n−1 的路径,按任意顺序返回答案。
图的表示如下: graph[i] \texttt{graph[i]} graph[i] 是从结点 i \texttt{i} i 可以访问的所有结点的列表(即从结点 i \texttt{i} i 到结点 graph[i][j] \texttt{graph[i][j]} graph[i][j] 存在一条有向边)。
示例
示例 1:

输入:
graph
=
[[1,2],[3],[3],[]]
\texttt{graph = [[1,2],[3],[3],[]]}
graph = [[1,2],[3],[3],[]]
输出:
[[0,1,3],[0,2,3]]
\texttt{[[0,1,3],[0,2,3]]}
[[0,1,3],[0,2,3]]
解释:有两条路径:
0
→
1
→
3
\texttt{0} \rightarrow \texttt{1} \rightarrow \texttt{3}
0→1→3 和
0
→
2
→
3
\texttt{0} \rightarrow \texttt{2} \rightarrow \texttt{3}
0→2→3。
示例 2:

输入:
graph
=
[[4,3,1],[3,2,4],[3],[4],[]]
\texttt{graph = [[4,3,1],[3,2,4],[3],[4],[]]}
graph = [[4,3,1],[3,2,4],[3],[4],[]]
输出:
[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
\texttt{[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]}
[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
数据范围
- n = graph.length \texttt{n} = \texttt{graph.length} n=graph.length
- 2 ≤ n ≤ 15 \texttt{2} \le \texttt{n} \le \texttt{15} 2≤n≤15
- 0 ≤ graph[i][j] < n \texttt{0} \le \texttt{graph[i][j]} < \texttt{n} 0≤graph[i][j]<n
- graph[i][j] ≠ i \texttt{graph[i][j]} \ne \texttt{i} graph[i][j]=i(即不存在自环)
- graph[i] \texttt{graph[i]} graph[i] 中的所有元素各不相同
- 保证输入为有向无环图
解法
思路和算法
这道题要求找到所有从结点 0 0 0 到结点 n − 1 n - 1 n−1 的路径。由于给定的图是有向无环图,因此图中的任意一条路径都不会访问同一个结点两次,路径的长度一定是有限的。可以使用回溯得到所有路径。
从结点 0 0 0 出发。对于每个访问到的结点 node \textit{node} node,执行如下操作。
-
将 node \textit{node} node 添加到路径的末尾。
-
判断 node \textit{node} node 是否等于 n − 1 n - 1 n−1,执行相应的操作。
-
如果 node = n − 1 \textit{node} = n - 1 node=n−1,则找到一条从结点 0 0 0 到结点 n − 1 n - 1 n−1 的路径,将路径添加到答案中。
-
如果 node ≠ n − 1 \textit{node} \ne n - 1 node=n−1,则对于 graph [ node ] \textit{graph}[\textit{node}] graph[node] 中的每个结点 next \textit{next} next,递归地访问 next \textit{next} next。
-
-
将 node \textit{node} node 从路径的末尾移除。
遍历结束时,即可得到所有从结点 0 0 0 到结点 n − 1 n - 1 n−1 的路径。
代码
class Solution {
List<List<Integer>> allPaths = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
int n;
int[][] graph;
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
this.n = graph.length;
this.graph = graph;
backtrack(0);
return allPaths;
}
public void backtrack(int node) {
temp.add(node);
if (node == n - 1) {
allPaths.add(new ArrayList<Integer>(temp));
} else {
int[] nextNodes = graph[node];
for (int next : nextNodes) {
backtrack(next);
}
}
temp.remove(temp.size() - 1);
}
}
复杂度分析
-
时间复杂度: O ( n × 2 n ) O(n \times 2^n) O(n×2n),其中 n n n 是图中的结点数。路径数最多是 2 n 2^n 2n,对于每条路径需要 O ( n ) O(n) O(n) 的时间添加到答案中,因此时间复杂度是 O ( n × 2 n ) O(n \times 2^n) O(n×2n)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是图中的结点数。存储当前路径的列表和递归调用栈需要 O ( n ) O(n) O(n) 的空间。注意返回值不计入空间复杂度。

108

被折叠的 条评论
为什么被折叠?



