Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
题目来源:LeetCode-节点间通路
节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
示例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。
图中可能存在自环和平行边。
二、思路分析:
思路一:
首先设置访问状态数组
使用DFS「深度优先搜索」进行递归搜索
逐渐压缩搜索区间,直至最终找到start与target在同一个路径内,则说明查找成功
当出现闭环时,则会出现死循环情况,必须在每次递归的过程中标志已走的路径。
当正序递归搜索时,会出现超时的情况,所以采用逆序搜索的方法解决。
思路二:
构建Map<Integer,List>
进行深度优先遍历
判断当前节点是否在map中存在通路节点
使用HashSet记录已经访问过的节点。
三、AC 代码:
思路一:
class AnimalShelf {
private boolean[] visitArray = null;
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
this.visitArray = new boolean[graph.length];
return helpful(graph, start, target);
}
private boolean helpful(int[][] graph, int start, int target) {
for (int i = 0; i < graph.length; ++i) {
if (!visitArray[i]) {
if (graph[i][0] == start && graph[i][1] == target) return true;
visitArray[i] = true;
if (graph[i][1] == target && helpful(graph, start, graph[i][0])) return true;
visitArray[i] = false;
}
}
return false;
}
}
复制代码
思路二:
class Solution {
Set<Integer> visitSet = new HashSet<>();
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
Map<Integer, List<Integer>> tempMap = new HashMap<>();
for (int[] a : graph) {
tempMap.computeIfAbsent(a[0], o -> new ArrayList<>()).add(a[1]);
}
if (start == target) {
return true;
}
if (!tempMap.containsKey(start)) {
return false;
}
return DFS(start, target, tempMap);
}
public boolean DFS(int current, int target, Map<Integer, List<Integer>> midMap) {
if (current == target) {
return true;
}
if (!midMap.containsKey(current)) {
return false;
}
visitSet.add(current);
for (int val : midMap.get(current)) {
if (!visitSet.contains(val)) {
if (DFS(val, target, midMap)) {
return true;
}
}
}
return false;
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END