[LeetCode] All Paths From Source to Target 從起點到目標點到所有路徑


 

Given a directed, acyclic graph of N nodes.  Find all possible paths from node 0 to node N-1, and return them in any order.

The graph is given as follows:  the nodes are 0, 1, ..., graph.length - 1.  graph[i] is a list of all nodes j for which the edge (i, j) exists.

Example:
Input: [[1,2], [3], [3], []] 
Output: [[0,1,3],[0,2,3]] 
Explanation: The graph looks like this:
0--->1
|    |
v    v
2--->3
There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3.

Note:

  • The number of nodes in the graph will be in the range [2, 15].
  • You can print different paths in any order, but you should keep the order of nodes inside one path.

 

這道題給了我們一個無回路有向圖,包含N個結點,然后讓我們找出所有可能的從結點0到結點N-1的路徑。這個圖的數據是通過一個類似鄰接鏈表的二維數組給的,最開始的時候博主沒看懂輸入數據的意思,其實很簡單,我們來看例子中的input,[[1,2], [3], [3], []],這是一個二維數組,最外層的數組里面有四個小數組,每個小數組其實就是和當前結點相通的鄰結點,由於是有向圖,所以只能是當前結點到鄰結點,反過來不一定行。那么結點0的鄰結點就是結點1和2,結點1的鄰結點就是結點3,結點2的鄰結點也是3,結點3沒有鄰結點。那么其實這道題的本質就是遍歷鄰接鏈表,由於要列出所有路徑情況,那么遞歸就是不二之選了。我們用cur來表示當前遍歷到的結點,初始化為0,然后在遞歸函數中,先將其加入路徑path,如果cur等於N-1了,那么說明到達結點N-1了,將path加入結果res。否則我們再遍歷cur的鄰接結點,調用遞歸函數即可,參見代碼如下:

 

解法一:

class Solution {
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        vector<vector<int>> res;
        helper(graph, 0, {}, res);
        return res;
    }
    void helper(vector<vector<int>>& graph, int cur, vector<int> path, vector<vector<int>>& res) {
        path.push_back(cur);
        if (cur == graph.size() - 1) res.push_back(path);
        else for (int neigh : graph[cur]) helper(graph, neigh, path, res);
    }
};

 

下面這種解法也是遞歸,不過寫法稍有不同,遞歸函數直接返回結果,這樣參數就少了許多,但是思路還是一樣的,如果cur等於N-1了,直接將cur先裝入數組,再裝入結果res中返回。否則就遍歷cur的鄰接結點,對於每個鄰接結點,先調用遞歸函數,然后遍歷其返回的結果,對於每個遍歷到的path,將cur加到數組首位置,然后將path加入結果res中即可,這有點像是回溯的思路,路徑是從后往前組成的,參見代碼如下:

 

解法二:

class Solution {
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        return helper(graph, 0);
    }
    vector<vector<int>> helper(vector<vector<int>>& graph, int cur) {
        if (cur == graph.size() - 1) {
            return {{graph.size() - 1}};
        }
        vector<vector<int>> res;
        for (int neigh : graph[cur]) {
            for (auto path : helper(graph, neigh)) {
                path.insert(path.begin(), cur);
                res.push_back(path);
            }
        }
        return res;
    }
};

 

類似題目:

https://leetcode.com/problems/all-paths-from-source-to-target/solution/

https://leetcode.com/problems/all-paths-from-source-to-target/discuss/121135/6-lines-C++-dfs

https://leetcode.com/problems/all-paths-from-source-to-target/discuss/118691/Easy-and-Concise-DFS-Solution-C++-2-line-Python

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM