質問:
2次元配列グラフで表されるnノードの有向非巡回グラフを前提として、0からn-1までのすべてのパスを見つけて出力してください(順序付けする必要はありません)。
グラフのi番目の配列のセルはすべて、有向グラフのノードiが到達できる次のノードを表します。→a)空の場合、次のノードはありません。
例1:
入力:graph = [[1,2]、[3]、[3]、[]]
出力:[[0,1,3]、[0,2,3]]
説明:2つのパスがあります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]]
分析:
タイトルは、すべてのn-1のノード0からノードn-1までのすべてのパスを一覧表示するように求めているため、深さ優先探索がより適切な選択です。
深さ優先探索は通常再帰的に実行されます。探索はノード0から始まります。ノードiが探索されるたびに、ノードが最初にパスに追加されます。ノードがノードn-1の場合、ノード0からのパスが見つかります。 。ノードn-1へのパス。そうでない場合は、graph [i]から隣接する各ノードを見つけ、同じ方法で検索します。ノードiから到達できるすべてのノードが検索されると、前のノードに戻って他の隣接ノードを検索します。前のノードに戻る前に、ノードiをパスから削除する必要があります。このプロセスは、次の再帰コードを使用して実行できます。
このコードでは、pathは現在のパス内のすべてのノードを記録し、resultは見つかったすべてのパスを記録します。アピールコードはノードが訪問されたかどうかを判断しません。通常、ノードが訪問されたかどうかを判断する必要があります。グラフ検索中に、リング内のノードへの繰り返しアクセスを回避できます。問題により、グラフが有向非巡回グラフであることがすでに明らかになっているため
、リング内のノードコードに繰り返しアクセスすることを心配する必要はありません。
package com.kuang;
import java.util.LinkedList;
import java.util.List;
public class AllPathsSourceTarget {
public static void main(String[] args) {
AllPathsSourceTarget allPathsSourceTarget = new AllPathsSourceTarget();
int[][] graph = {
{
1,2},{
3},{
3},{
}};
List<List<Integer>> lists = allPathsSourceTarget.allPathsSourceTarget(graph);
System.out.println(lists);
}
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
List<List<Integer>> result = new LinkedList<>();
List<Integer> path = new LinkedList<>();
dfs(0,graph,path,result);
return result;
}
private void dfs(int source, int[][] graph, List<Integer> path, List<List<Integer>> result) {
path.add(source);
// 如果该节点正好是节点n-1,那么就找到一条从节点0到节点n-1的路径
if (source == graph.length-1){
// 将路径添加到结果集中
result.add(new LinkedList<Integer>(path));
}else {
for (int next:graph[source]){
dfs(next,graph,path,result);
}
}
//在回到前一个节点之前,需要将节点i从路径中删除
path.remove(path.size()-1);
}
}