题目链接
节点间通路
题目描述
注意点
- 图是有向图
- 节点编号大于等于 0 小于 n
- 图中可能存在自环和平行边
解答思路
- 初始想到的是使用广度优先遍历,从start开始,存储每个点所能到达的其他节点集合,直到到达target或者不能到达新的节点为止,需要注意的是,图中可能存在自环和平行边,所以还需要使用一个visited数组存储已经到达过的节点,防止死循环,但是最终还是超时了
- 注意到在广度优先遍历的过程中寻找每个节点所能到达的相邻节点每次都需要从前往后遍历整个graph数组,这是相当耗时的,为了减少这个过程,使用map存储每个节点所能到达的相邻节点,并且初始就遍历一次graph将map初始化,后续只需要根据map广度寻找每次所能到达的节点即可
代码
class Solution {
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
// 存储点对应的有向边
Map<Integer, List<Integer>> map = new HashMap<>(n);
for (int i = 0; i < graph.length; i++) {
if (map.get(graph[i][0]) == null) {
List<Integer> list = new ArrayList<>();
list.add(graph[i][1]);
map.put(graph[i][0], list);
} else {
map.get(graph[i][0]).add(graph[i][1]);
}
}
boolean[] visited = new boolean[graph.length];
Deque<Integer> dq = new ArrayDeque<>();
dq.offerLast(start);
visited[start] = true;
while (!dq.isEmpty()) {
int node1 = dq.pollFirst();
if (map.get(node1) == null) {
continue;
}
for (int node2 : map.get(node1)) {
if (node2 == target) {
return true;
}
if (visited[node2]) {
continue;
}
dq.offerLast(node2);
visited[node2] = true;
}
}
return false;
}
}
关键点
- 广度优先遍历的思想
- 使用visited数组存储哪些节点已经到达过
- 使用map存储每个节点所能到达的相邻节点