面试题 04.01. 节点间通路
节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
示例1:
输入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2
输出:true
示例2:
输入:n = 5, graph = [[0, 1], [0, 2], [0, 4], [0, 4], [0, 1], [1, 3], [1, 4], [1, 3], [2, 3], [3, 4]], start = 0, target = 4
输出 true
提示:
节点数量n在[0, 1e5]范围内。
节点编号大于等于 0 小于 n。
图中可能存在自环和平行边。
方法1:邻接表+BFS
List<Integer>[] adj;
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
this.adj = new ArrayList[n];
buildAdj(graph);
boolean[] vis = new boolean[n];
Queue<Integer> q = new LinkedList<>();
q.offer(start);
vis[start] = true;
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
int cur = q.poll();
List<Integer> nextList = adj[cur];
if (nextList == null) continue;
for (int next : nextList) {
if (next == target) return true;
if (vis[next]) continue;
vis[next] = true;
q.offer(next);
}
}
}
return false;
}
private void buildAdj(int[][] graph) {
for (int[] edge : graph) {
int u = edge[0], v = edge[1];
if (adj[u] == null) adj[u] = new ArrayList<>();
adj[u].add(v);
}
}
方法2:HashMap建图+BFS
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
buildGraph(graph);
Queue<Integer> q = new LinkedList<>();
boolean[] vis = new boolean[n];
q.offer(start);
vis[start] = true;
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
int cur = q.poll();
Set<Integer> nextSet = g.get(cur);
if (nextSet == null) continue;
for (int next : nextSet) {
if (next == target) return true;
if (vis[next]) continue;
vis[next] = true;
q.offer(next);
}
}
}
return false;
}
Map<Integer, Set<Integer>> g = new HashMap<>();
private void buildGraph(int[][] graph) {
for (int[] e : graph) {
int u = e[0], v = e[1];
Set<Integer> set = g.getOrDefault(u, new HashSet<>());
set.add(v);
g.put(u, set);
}
}
方法3:邻接表+DFS
boolean[] vis;
int n;
List<Integer>[] g;
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
this.n = n;
this.vis = new boolean[this.n];
this.g = new ArrayList[this.n];
buildGraph(graph);
return dfs(start, target);
}
private boolean dfs(int start, int target) {
if (start == target) return true;
if (vis[start]) return false;
vis[start] = true;
List<Integer> nextList = g[start];
if (nextList == null) return false;
for (int next : nextList) {
if (dfs(next, target)) return true;
}
return false;
}
private void buildGraph(int[][] graph) {
for (int[] e : graph) {
int u = e[0], v = e[1];
if (g[u] == null) g[u] = new ArrayList<>();
g[u].add(v);
}
}