好久没做过图类型的题了,这是在LeetCode上的第一道图的题。
题目
节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
示例
输入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2
输出:true
提示:
- 节点数量
n
在[0, 1e5]
范围内。 - 节点编号大于等于
0
小于n
。 - 图中可能存在自环和平行边。
思路
方法一:DFS
map
创建一个领接表,visited
标记访问过的节点dfs
通过入口start遍历每一种可能
方法二:BFS
map
创建一个领接表visited
标记访问过的节点- 创建
queue
队列进行bfs
遍历
C++代码
class Solution {
private:
//方法一:dfs
//用map存储领接表,比用动态数组下标耗费空间小
unordered_map<int, vector<int> > map;
vector<bool> visited;
public:
bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
visited.resize(n,false);
//存储领接表
for(auto& g : graph) {
map[g[0]].emplace_back(g[1]);
}
return dfs(start, target);
}
bool dfs(int start, int target) {
if(start == target) return true;
//如果访问过了就相当于找不到,返回false
if(visited[start]) return false;
//标记start行,表示访问过了
visited[start] = true;
//遍历start行,dfs深搜找target
for(auto& ms : map[start]) {
if(dfs(ms, target)) return true;
}
return false;
}
};
class Solution {
public:
bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
//方法二:bfs
//用map存储领接表,比用动态数组下标耗费空间小
unordered_map<int, vector<int> > map;
vector<int> visited(n,false);
//存储领接表
for(auto& g : graph) {
map[g[0]].emplace_back(g[1]);
}
queue<int> q;
q.push(start);
while(!q.empty()) {
int top = q.front(); q.pop();
if(top == target) return true;
visited[top] = true;
for(auto& ms : map[top]) {
if(!visited[ms])
q.push(ms);
}
}
return false;
}
};
Java代码
//dfs
class Solution {
Map<Integer, List<Integer>> map = new HashMap<>();
boolean[] visited;
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
visited = new boolean[n];
for(int[] g : graph) {
if(!map.containsKey(g[0])) {
//创建有key的空列表
map.put(g[0], new ArrayList<>());
}
map.get(g[0]).add(g[1]);
}
return dfs(start, target);
}
boolean dfs(int start, int target) {
if(start == target) return true;
if(visited[start]) return false;
visited[start] = true;
//Java需要注意的点,防止map.get(key)空指针异常
if(map.get(start) == null) return false;
for(Integer ms : map.get(start)) {
if(dfs(ms, target)) return true;
}
return false;
}
}
//bfs
class Solution {
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
Map<Integer, List<Integer>> map = new HashMap<>();
boolean[] visited = new boolean[n];
LinkedList<Integer> q = new LinkedList<>();
for(int[] g : graph) {
if(!map.containsKey(g[0])) {
map.put(g[0], new ArrayList<>());
}
map.get(g[0]).add(g[1]);
}
q.add(start);
while(!q.isEmpty()) {
int top = q.pop();
visited[top] = true;
if(top == target) return true;
if(map.get(top) == null) continue;
for(Integer mt : map.get(top)) {
if(!visited[mt])
q.add(mt);
}
}
return false;
}
}