LeetCode 所有可能的路径(回溯法)

给一个有 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.

提示:

结点的数量会在范围 [2, 15] 内。
你可以把路径以任意顺序输出,但在路径内的结点的顺序必须保证。

思 路 分 析 : \color{blue}{思路分析:} 图的路径搜索问题,典型的回溯法题。
我们以0为起点进行搜索,查找0能够到达的所有{A,B,C},在分别以A、B、C为起点进行递归搜索,直到到达了target = n - 1。

class Solution {
public:
	vector<vector<int>> resVec;//存储所有路径
	vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
		int n = graph.size();
		vector<int> tempRes(1, 0);//单条正在搜索的路径
		vector<int> visited(n, false);//这条路径已经访问过的点
		visited[0] = true;//标记访问
		dfs(graph, n - 1, visited, tempRes, 0, 1);//以0为起点开始搜索
		return resVec;
	}
    //以nowIndex为起点开始搜索到达target的路径,visited代表从0到达nowIndex已经走过的节点,tempRes代表已经走过的路径,haveVisited表示已经搜索的节点个数
	void dfs(vector<vector<int>>& graph, int target, vector<int> &visited, vector<int> tempRes, int nowIndex, int haveVisited) {
		if (nowIndex == target) {//如果到达了终点,放入结果
			resVec.push_back(tempRes);
			return;
		}
		tempRes.push_back(1);//在路径中新增位置用于放入即将访问的下一个节点
        //搜索nextIndex可到达的所有的节点
		for (auto nextIndex : graph[nowIndex]) {
			if (!visited[nextIndex]) {//只有这个点没有访问过才有意义
				tempRes[haveVisited] = nextIndex;//放入路径
				visited[nextIndex] = true;//标记访问
				dfs(graph, target, visited, tempRes, nextIndex, haveVisited + 1);//再次以nextIndex为起点进行搜索
				visited[nextIndex] = false;//注意,需要取消访问标记
			}
		}
	}
};

LeetCode 所有可能的路径(回溯法)_第1张图片

你可能感兴趣的:(LeetCode,回溯法,图)