[LeetCode] 1971. Find if Path Exists in Graph

There is a bi-directional graph with n vertices, where each vertex is labeled from 0 to n - 1 (inclusive). The edges in the graph are represented as a 2D integer array edges, where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex ui and vertex vi. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself.

You want to determine if there is a valid path that exists from vertex source to vertex destination.

Given edges and the integers nsource, and destination, return true if there is a valid path from source to destination, or false otherwise.

Example 1:

Input: n = 3, edges = [[0,1],[1,2],[2,0]], source = 0, destination = 2
Output: true
Explanation: There are two paths from vertex 0 to vertex 2:
- 0 → 1 → 2
- 0 → 2

Example 2:

Input: n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], source = 0, destination = 5
Output: false
Explanation: There is no path from vertex 0 to vertex 5.

Constraints:

  • 1 <= n <= 2 * 105
  • 0 <= edges.length <= 2 * 105
  • edges[i].length == 2
  • 0 <= ui, vi <= n - 1
  • ui != vi
  • 0 <= source, destination <= n - 1
  • There are no duplicate edges.
  • There are no self edges.

寻找图中是否存在路径。

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 source 开始,到顶点 destination 结束的 有效路径 。

给你数组 edges 和整数 n、source 和 destination,如果从 source 到 destination 存在 有效路径 ,则返回 true,否则返回 false 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-if-path-exists-in-graph
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是一道图论的题目,这里我给出三种思路,分别是BFS,DFS 和 并查集。题意很好理解,给了一些定点,其中包含 source 和 destination,请问 source 和 destination 是否连通。

BFS - 需要额外的 boolean 数组记录每个 node 是否被访问过,避免死循环

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public boolean validPath(int n, int[][] edges, int source, int destination) {
 3         List<List<Integer>> g = new ArrayList<>();
 4         for (int i = 0; i < n; i++) {
 5             g.add(new ArrayList<>());
 6         }
 7         
 8         for (int[] e : edges) {
 9             g.get(e[0]).add(e[1]);
10             g.get(e[1]).add(e[0]);
11         }
12         
13         boolean[] visited = new boolean[n];
14         Queue<Integer> queue = new LinkedList<>();
15         queue.offer(source);
16         while (!queue.isEmpty()) {
17             int cur = queue.poll();
18             if (cur == destination) {
19                 return true;
20             }
21             visited[cur] = true;
22             int size = g.get(cur).size();
23             for (int i = 0; i < size; i++) {
24                 int next = g.get(cur).get(i);
25                 if (visited[next] == false) {
26                     queue.offer(next);
27                 }
28             }
29         }
30         return false;
31     }
32 }

 

DFS - 也需要额外的 boolean 数组记录每个 node 是否被访问过,避免死循环

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     private boolean[] visited;
 3     private List<List<Integer>> g;
 4 
 5     public boolean validPath(int n, int[][] edges, int source, int destination) {
 6         visited = new boolean[n];
 7         g = new ArrayList<>();
 8         for (int i = 0; i < n; i++) {
 9             g.add(new ArrayList<>());
10         }
11         for (int[] e : edges) {
12             g.get(e[0]).add(e[1]);
13             g.get(e[1]).add(e[0]);
14         }
15         return dfs(source, destination);
16     }
17 
18     private boolean dfs(int source, int destination) {
19         if (source == destination) {
20             return true;
21         }
22         visited[source] = true;
23         for (int next : g.get(source)) {
24             if (!visited[next] && dfs(next, destination)) {
25                 return true;
26             }
27         }
28         return false;
29     }
30 }

 

Union Find - P 数组记录的是每个 node 的父节点,最后判断 source 和 destination 的父节点是否相同

时间O(V + E)

空间O(V + E)

Java实现

 1 class Solution {
 2     private int[] p;
 3 
 4     public boolean validPath(int n, int[][] edges, int source, int destination) {
 5         p = new int[n];
 6         for (int i = 0; i < n; i++) {
 7             p[i] = i;
 8         }
 9         for (int[] e : edges) {
10             p[find(e[0])] = find(e[1]);
11         }
12         return find(source) == find(destination);
13     }
14 
15     private int find(int x) {
16         if (p[x] != x) {
17             p[x] = find(p[x]);
18         }
19         return p[x];
20     }
21 }

 

LeetCode 题目总结

posted @ 2022-12-19 14:24  CNoodle  阅读(322)  评论(0编辑  收藏  举报