题目:
给你一个有 n
个节点的 有向无环图(DAG),请你找出所有从节点 0
到节点 n-1
的路径并输出(不要求按特定顺序)
graph[i]
是一个从节点 i
可以访问的所有节点的列表(即从节点 i
到节点 graph[i][j]
存在一条有向边)。
示例:
- 输入: g r a p h = [ [ 1 , 2 ] , [ 3 ] , [ 3 ] , [ ] ] graph = [[1,2],[3],[3],[]] graph=[[1,2],[3],[3],[]]
- 输出: [ [ 0 , 1 , 3 ] , [ 0 , 2 , 3 ] ] [[0,1,3],[0,2,3]] [[0,1,3],[0,2,3]]
- 解释: 有两条路径 0 − > 1 − > 3 0 -> 1 -> 3 0−>1−>3 和 0 − > 2 − > 3 0 -> 2 -> 3 0−>2−>3
解题思路:(深搜DFS)
-
确定递归函数和参数
定义res
二维数组存放结果集(各个从0->终点
的路径),定义path
一维数组存放遍历到的单一路径。然后递归函数中的第一个参数接收题目中传入的用来遍历的图graph
,第二个参数x
接收当前遍历到的节点(从0开始遍历):vector<vector<int>> res; vector<int> path; void dfs(vector<vector<int>>& graph, int x)
-
确定终止条件
若当前遍历节点等于终点,即x == graph.size() - 1
,则将当前路径path
加入到结果集res
中,代表找到了一条路径,并返回。if(x == graph.size() - 1){ res.push_back(path); return; }
-
处理以目前搜索节点出发的路径
首先遍历当前节点与哪些节点相连,依次取出,首先加入到当前路径path
中,然后递归,之后需要回溯。for(int i = 0; i < graph[x].size(); i++){ path.push_back(graph[x][i]); dfs(graph, graph[x][i]); path.pop_back(); }
C++版整体代码
class Solution {
public:
vector<vector<int>> res; // 结果集
vector<int> path; // 单一路径
void dfs(vector<vector<int>>& graph, int x){ // x为当前遍历的节点
if(x == graph.size() - 1){ // 终止条件
res.push_back(path);
return;
}
for(int i = 0; i < graph[x].size(); i++){ // 遍历以当前节点出发的节点
path.push_back(graph[x][i]);
dfs(graph, graph[x][i]); // 递归
path.pop_back(); // 回溯
}
}
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
path.push_back(0); // 从0号节点出发
dfs(graph, 0);
return res;
}
};
Java版整体代码
class Solution {
List<List<Integer>> res;
List<Integer> path = new ArrayList<>();
public void dfs(int[][] graph, int x){
if(x == graph.length - 1){
res.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < graph[x].length; i++){
path.add(graph[x][i]);
dfs(graph, graph[x][i]);
path.remove(path.size() - 1);
}
}
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
res = new ArrayList<>();
path = new ArrayList<>();
path.add(0);
dfs(graph, 0);
return res;
}
}