力扣 leetcode 797. 所有可能的路径

问题描述

给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)

graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j] 存在一条有向边)。

提示:

  • n == graph.length
  • 2 <= n <= 15
  • 0 <= graph[i][j] < n
  • graph[i][j] != i(即不存在自环)
  • graph[i] 中的所有元素 互不相同
  • 保证输入为 有向无环图(DAG)

示例

示例 1:

输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3

示例 2:

输入:graph = [[4,3,1],[3,2,4],[3],[4],[]]
输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]

解题思路

本题要输出路径,因此优先选择 DFS 。这里找到一条路径很简单,关键是要把路径记录下来。最简单的做法是在搜索最短路径的过程中记录路径,借助 DFS 的特性,我们可以用一个数组保存当前路径的节点序号,当找到目标节点后,就将路径保存下来。

class Solution {
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        stack<int> s;
        vector<int> path(graph.size()); // 记录当前路径
        int idx = 0;
        vector<vector<int>> res;
        const int n = graph.size() - 1;
        s.push(0);
        while(!s.empty()){ // DFS
            int node = s.top();
            s.pop();
            if(node == -1){ // 这里node为-1表示,这是栈中某个节点的子节点已经全部遍历完毕了
                idx--;
            }
            else if(node == n){ // 到达目标节点,将路径保存下来
                path[idx++] = node;
                vector<int> r(idx);
                for(int j = 0; j < idx; j++){
                    r[j] = path[j];
                }
                res.push_back(r);
                idx--;
            }
            else{ // 不是目标节点,继续遍历
                path[idx++] = node;
                s.push(-1); // 这里将-1 加入是为了分隔每个节点遍历的子节点
                for(int i = 0; i < graph[node].size(); i++){
                    s.push(graph[node][i]);
                }
            }
        }
        return res;  
    }
};
posted @ 2022-12-06 23:50  greatestchen  阅读(30)  评论(0编辑  收藏  举报