
class Solution {
public:
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
vector<vector<int>> ret;
int num = graph.size() - 1;
vector<int> path;
AllPath(graph, ret,path,0,num);
return ret;
}
void AllPath(vector<vector<int>>& graph, vector<vector<int>>& ret, vector<int> path,int begin,int num)
{
path.push_back(begin);
if (begin == num)
{
ret.push_back(path);
return;
}
for (int i = 0; i < graph[begin].size(); i++)
{
AllPath(graph, ret, path, graph[begin][i], num);
}
return;
}
};
当拿到这个题的时候还是有一点点的思路,实在不行就暴力求解,但是这个题暴力求解是很复杂的,我看来是不能实现的,因为你不知道数组有多少个一维数组,并且每个一维数组里边的数据个数也是不能确定的。所以暴力求解是不能实现的。
因为和循环类似的问题就是递归了,并且看到结点的数字会在范围2,15内,那这不就是怕递归层数过多。所以自然就用递归来解决,
在最初的递归中我想的是一层层往回退,你不是要到达num的节点么,我先看num-1能不能到,能的话我再去看num-2能不能到num-1,但是这种遇到0直接到3这种情况处理起来就很麻烦。
所以还是正着走好一点,正着走就要解决几个问题。
-
当你走到最后的结点也就是目的地的时候你就需要停下来,这是递归的一个边界条件。所以这就要求你函数的参数里边要有当前走到的结点,和最终目的地结点两个参数
-
当你走到一半的时候发现这条路不能走的时候要返回。并且把走过的路径不保存。就比如你现在有一条路是1-2-3-5,但是你走到1-2的时候去了4结点,4不能到达5你要退回到2.
-
当你发现你当前节点就是你要到达的结点的时候要保存当前的路径数组进去,并且还能退回去,可能还有其他可能, 比如上来直接有0-5的路径,你还是要去遍历0-1,0-2这些结点。
其实在用递归写问题的经常有感觉,我感觉自己写的不是特别对就是能实现我想要的功能。这里我们还是创建另外一个函数,因为提供的函数参数是不够的。
void AllPath(vector<vector<int>>& graph, vector<vector<int>>& ret, vector<int> path,int begin,int num)
{
path.push_back(begin);
if (begin == num)
{
ret.push_back(path);
return;
}
for (int i = 0; i < graph[begin].size(); i++)
{
AllPath(graph, ret, path, graph[begin][i], num);
}
return;
}
自己最初的时候没有想明白,这里我认为最关键的地方就是vector<int> path,这里不能用引用,这样就不会如果这条路径失败了, 或者说这条路径插入了新的路径位置不会影响上层递归往其他下层函数传递的数据。

如果加上引用的话,会发现我们后边的数组会把前边所有的路径都保存下来在再去加自己的路径。
当我们的开始结点和我们最终想到达的结点相同的时候,就把这个拷贝出来的一维数组path插入到二维数组里边,如果当我们的走到尽头走不了但还没到终点的时候就不会插入进入。