给一个有 n
个结点的有向无环图,找到所有从 0
到 n-1
的路径并输出(不要求按顺序)
二维数组的第 i 个数组中的单元都表示有向图中 i 号结点所能到达的下一些结点(译者注:有向图是有方向的,即规定了a→b你就不能从b→a)空就是没有下一个结点了。
示例: 输入: [[1,2], [3], [3], []] 输出: [[0,1,3],[0,2,3]] 解释: 图是这样的: 0--->1 | | v v 2--->3 这有两条路: 0 -> 1 -> 3 和 0 -> 2 -> 3.
基本思路:
-
首先通过输入做出一个邻接表。(不知道什么是邻接表的同学,可以先百度一下)
-
然后就是递归+回溯即可。
代码上基本都有注释,仔细体会递归主体那一部分。
class Solution {
public:
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
int W = graph.size();
// 创建邻接表
vector<vector<int>> LinMap(W, vector<int>(W, 0));
for (int i = 0; i < W; i++) {
for (int N : graph[i]) {
LinMap[i][N] = 1;
}
}
// Target就是我们要找的最后的一个节点,也就是n-1(n为节点个数)
int Target = W - 1;
vector<int> Temp_Res(1,0);
_allPathsSourceTarget(LinMap, Temp_Res, 0, Target);
return Res;
}
// LinMap邻接表 Temp_Res临时储存结果的数组 Now_P现在正在找的节点 Target我们要找的最后的一个节点
void _allPathsSourceTarget(vector<vector<int>>& LinMap, vector<int> Temp_Res, int Now_P, int Target) {
//已经找到末尾了 直接返回即可
if (Now_P == Target) {
Temp_Res.push_back(Now_P);
Res.push_back(Temp_Res);
return;
}
//递归的主体。
for (int i = 0; i < LinMap[Now_P].size(); i++) {
// 通过邻接表来判断下一个节点在哪。
if (LinMap[Now_P][i] == 1) {
Temp_Res.push_back(i); //将某个节点加入进去。
_allPathsSourceTarget(LinMap, Temp_Res, i, Target);
Temp_Res.pop_back(); //回溯一下
}
}
return;
}
private:
vector<vector<int>> Res;
};