题目一
力扣:797. 所有可能的路径
思路
一道经典的图论从源点到汇点求路径问题
1、读懂题目,他给的数据形式很简单,非常实用,总结一句话就是,gragh[0]存的就是第0个点直接和哪些点相连,很适合求路径使用。
BFS
1、提到BFS,我们第一反应就是用队列维护。
2、但是平常的都是用队列维护一个个的点,这个题要求出所有的路径,问题变化了,我要求所有的源点到汇点的路径,我们发现单纯的用维护点的方法行不通了,不适合维护路径。
3、所以我们大胆点,每次都用队列维护当前路径即可,每次弹出的路径的最后一个元素就是上一次新加入的,用那个点继续扩展即可。别的思路都一样,既然要求路径,我就用队列维护路径就好了。
DFS:经典回溯思路
1、这个没什么好说的,有向无环图,不存在死循环,不用visit数组标识是否走过。
2、dfs的时候,到终点,当前维护的全局tmp直接压入答案即可,每扩展到一个点,将之压入全局tmp临时路径,当该点对应的路径都找完了,回溯回来的时候(即该点对应的dfs结束),那么这个点无用了(因为这个点扩充的路径没了),所以从tmp中删除,这么做也因为tmp临时路径是全局的。
代码
BFS
1、注意,一定要随应变,既然求的是路径,那么就直接维护路径好了
class Solution {
public:
vector<vector<int>> ans;
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
int n = graph.size();
queue<vector<int>> item;
vector<int> tmp;
tmp.push_back(0);//初始化
item.push(tmp);
while (!item.empty()) {
vector<int> point = item.front();//弹出路径
item.pop();
int p1 = point[point.size() - 1];//最后一个点是上一次新来的点,用这个点进行扩充
if (p1 == n - 1) {
//走到终点
ans.push_back(point);
continue;//说明这个路径没用了,继续循环
}
for (int p : graph[p1]) {
vector<int> tmps(point);//进行点的扩充
tmps.push_back(p);
item.push(tmps);
}
}
return ans;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
DFS
class Solution {
public:
vector<vector<int>> graph;
int n;
vector<vector<int>> ans;
vector<int> tmp;
void dfs(int point) {
if (point == n - 1) {
ans.push_back(tmp);
return;
}
for (int p : graph[point]) {
tmp.push_back(p);
dfs(p);
tmp.pop_back();
}
}
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
n = graph.size();
this->graph = graph;
tmp.push_back(0);
dfs(0);
return ans;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
扫描二维码关注公众号,回复:
13227244 查看本文章