Skip to content

Commit a0d4ef3

Browse files
authored
feat: add solutions to lc problem: No.1971 (doocs#3568)
No.1971.Find if Path Exists in Graph
1 parent 7023118 commit a0d4ef3

20 files changed

+907
-408
lines changed

solution/1900-1999/1971.Find if Path Exists in Graph/README.md

+304-136
Large diffs are not rendered by default.

solution/1900-1999/1971.Find if Path Exists in Graph/README_EN.md

+305-137
Large diffs are not rendered by default.

solution/1900-1999/1971.Find if Path Exists in Graph/Solution.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
class Solution {
22
public:
33
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
4-
vector<bool> vis(n);
54
vector<int> g[n];
6-
for (auto& e : edges) {
7-
int a = e[0], b = e[1];
8-
g[a].emplace_back(b);
9-
g[b].emplace_back(a);
5+
vector<bool> vis(n);
6+
for (const auto& e : edges) {
7+
int u = e[0], v = e[1];
8+
g[u].push_back(v);
9+
g[v].push_back(u);
1010
}
1111
function<bool(int)> dfs = [&](int i) -> bool {
1212
if (i == destination) {
1313
return true;
1414
}
1515
vis[i] = true;
16-
for (int& j : g[i]) {
16+
for (int j : g[i]) {
1717
if (!vis[j] && dfs(j)) {
1818
return true;
1919
}

solution/1900-1999/1971.Find if Path Exists in Graph/Solution.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ func validPath(n int, edges [][]int, source int, destination int) bool {
22
vis := make([]bool, n)
33
g := make([][]int, n)
44
for _, e := range edges {
5-
a, b := e[0], e[1]
6-
g[a] = append(g[a], b)
7-
g[b] = append(g[b], a)
5+
u, v := e[0], e[1]
6+
g[u] = append(g[u], v)
7+
g[v] = append(g[v], u)
88
}
99
var dfs func(int) bool
1010
dfs = func(i int) bool {
@@ -20,4 +20,4 @@ func validPath(n int, edges [][]int, source int, destination int) bool {
2020
return false
2121
}
2222
return dfs(source)
23-
}
23+
}

solution/1900-1999/1971.Find if Path Exists in Graph/Solution.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ class Solution {
44
private List<Integer>[] g;
55

66
public boolean validPath(int n, int[][] edges, int source, int destination) {
7+
this.destination = destination;
8+
vis = new boolean[n];
79
g = new List[n];
8-
Arrays.setAll(g, k -> new ArrayList<>());
10+
Arrays.setAll(g, i -> new ArrayList<>());
911
for (var e : edges) {
10-
int a = e[0], b = e[1];
11-
g[a].add(b);
12-
g[b].add(a);
12+
int u = e[0], v = e[1];
13+
g[u].add(v);
14+
g[v].add(u);
1315
}
14-
vis = new boolean[n];
15-
this.destination = destination;
1616
return dfs(source);
1717
}
1818

@@ -21,7 +21,7 @@ private boolean dfs(int i) {
2121
return true;
2222
}
2323
vis[i] = true;
24-
for (int j : g[i]) {
24+
for (var j : g[i]) {
2525
if (!vis[j] && dfs(j)) {
2626
return true;
2727
}

solution/1900-1999/1971.Find if Path Exists in Graph/Solution.py

+7-9
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ class Solution:
22
def validPath(
33
self, n: int, edges: List[List[int]], source: int, destination: int
44
) -> bool:
5-
def dfs(i):
5+
def dfs(i: int) -> bool:
66
if i == destination:
77
return True
8-
vis.add(i)
9-
for j in g[i]:
10-
if j not in vis and dfs(j):
11-
return True
12-
return False
8+
if i in vis:
9+
return False
10+
return any(dfs(j) for j in g[i])
1311

1412
g = [[] for _ in range(n)]
15-
for a, b in edges:
16-
g[a].append(b)
17-
g[b].append(a)
13+
for u, v in edges:
14+
g[u].append(v)
15+
g[v].append(u)
1816
vis = set()
1917
return dfs(source)
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
11
impl Solution {
22
pub fn valid_path(n: i32, edges: Vec<Vec<i32>>, source: i32, destination: i32) -> bool {
3-
let mut disjoint_set: Vec<i32> = vec![0; n as usize];
4-
// Initialize the set
5-
for i in 0..n {
6-
disjoint_set[i as usize] = i;
7-
}
8-
9-
// Traverse the edges
10-
for p_vec in &edges {
11-
let parent_one = Solution::find(p_vec[0], &mut disjoint_set);
12-
let parent_two = Solution::find(p_vec[1], &mut disjoint_set);
13-
disjoint_set[parent_one as usize] = parent_two;
14-
}
3+
let n = n as usize;
4+
let source = source as usize;
5+
let destination = destination as usize;
156

16-
let p_s = Solution::find(source, &mut disjoint_set);
17-
let p_d = Solution::find(destination, &mut disjoint_set);
7+
let mut g = vec![Vec::new(); n];
8+
let mut vis = vec![false; n];
189

19-
p_s == p_d
20-
}
10+
for e in edges {
11+
let u = e[0] as usize;
12+
let v = e[1] as usize;
13+
g[u].push(v);
14+
g[v].push(u);
15+
}
2116

22-
pub fn find(x: i32, d_set: &mut Vec<i32>) -> i32 {
23-
if d_set[x as usize] != x {
24-
d_set[x as usize] = Solution::find(d_set[x as usize], d_set);
17+
fn dfs(g: &Vec<Vec<usize>>, vis: &mut Vec<bool>, i: usize, destination: usize) -> bool {
18+
if i == destination {
19+
return true;
20+
}
21+
vis[i] = true;
22+
for &j in &g[i] {
23+
if !vis[j] && dfs(g, vis, j, destination) {
24+
return true;
25+
}
26+
}
27+
false
2528
}
26-
d_set[x as usize]
29+
30+
dfs(&g, &mut vis, source, destination)
2731
}
2832
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
function validPath(n: number, edges: number[][], source: number, destination: number): boolean {
22
const g: number[][] = Array.from({ length: n }, () => []);
3-
for (const [a, b] of edges) {
4-
g[a].push(b);
5-
g[b].push(a);
3+
for (const [u, v] of edges) {
4+
g[u].push(v);
5+
g[v].push(u);
66
}
7-
87
const vis = new Set<number>();
98
const dfs = (i: number) => {
109
if (i === destination) {
@@ -13,10 +12,8 @@ function validPath(n: number, edges: number[][], source: number, destination: nu
1312
if (vis.has(i)) {
1413
return false;
1514
}
16-
1715
vis.add(i);
1816
return g[i].some(dfs);
1917
};
20-
2118
return dfs(source);
2219
}

solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ class Solution {
22
public:
33
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
44
vector<vector<int>> g(n);
5-
for (auto& e : edges) {
6-
int a = e[0], b = e[1];
7-
g[a].push_back(b);
8-
g[b].push_back(a);
5+
for (const auto& e : edges) {
6+
int u = e[0], v = e[1];
7+
g[u].push_back(v);
8+
g[v].push_back(u);
99
}
1010
queue<int> q{{source}};
1111
vector<bool> vis(n);

solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
func validPath(n int, edges [][]int, source int, destination int) bool {
22
g := make([][]int, n)
33
for _, e := range edges {
4-
a, b := e[0], e[1]
5-
g[a] = append(g[a], b)
6-
g[b] = append(g[b], a)
4+
u, v := e[0], e[1]
5+
g[u] = append(g[u], v)
6+
g[v] = append(g[v], u)
77
}
88
q := []int{source}
99
vis := make([]bool, n)

solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ public boolean validPath(int n, int[][] edges, int source, int destination) {
33
List<Integer>[] g = new List[n];
44
Arrays.setAll(g, k -> new ArrayList<>());
55
for (var e : edges) {
6-
int a = e[0], b = e[1];
7-
g[a].add(b);
8-
g[b].add(a);
6+
int u = e[0], v = e[1];
7+
g[u].add(v);
8+
g[v].add(u);
99
}
1010
Deque<Integer> q = new ArrayDeque<>();
1111
q.offer(source);

solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ def validPath(
33
self, n: int, edges: List[List[int]], source: int, destination: int
44
) -> bool:
55
g = [[] for _ in range(n)]
6-
for a, b in edges:
7-
g[a].append(b)
8-
g[b].append(a)
9-
6+
for u, v in edges:
7+
g[u].append(v)
8+
g[v].append(u)
109
q = deque([source])
1110
vis = {source}
1211
while q:

solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,30 @@ use std::collections::{HashSet, VecDeque};
22

33
impl Solution {
44
pub fn valid_path(n: i32, edges: Vec<Vec<i32>>, source: i32, destination: i32) -> bool {
5-
let mut g = vec![HashSet::new(); n as usize];
6-
for e in edges {
7-
let a = e[0] as usize;
8-
let b = e[1] as usize;
9-
g[a].insert(b);
10-
g[b].insert(a);
5+
let n = n as usize;
6+
let source = source as usize;
7+
let destination = destination as usize;
8+
9+
let mut g = vec![Vec::new(); n];
10+
for edge in edges {
11+
let u = edge[0] as usize;
12+
let v = edge[1] as usize;
13+
g[u].push(v);
14+
g[v].push(u);
1115
}
1216

1317
let mut q = VecDeque::new();
14-
q.push_back(source as usize);
15-
let mut vis = vec![false; n as usize];
16-
vis[source as usize] = true;
18+
let mut vis = HashSet::new();
19+
q.push_back(source);
20+
vis.insert(source);
1721

1822
while let Some(i) = q.pop_front() {
19-
if i == (destination as usize) {
23+
if i == destination {
2024
return true;
2125
}
2226
for &j in &g[i] {
23-
if !vis[j] {
24-
vis[j] = true;
27+
if !vis.contains(&j) {
28+
vis.insert(j);
2529
q.push_back(j);
2630
}
2731
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
function validPath(n: number, edges: number[][], source: number, destination: number): boolean {
22
const g: number[][] = Array.from({ length: n }, () => []);
3-
4-
for (const [a, b] of edges) {
5-
g[a].push(b);
6-
g[b].push(a);
3+
for (const [u, v] of edges) {
4+
g[u].push(v);
5+
g[v].push(u);
76
}
8-
9-
const vis = new Set<number>();
7+
const vis = new Set<number>([source]);
108
const q = [source];
11-
129
while (q.length) {
1310
const i = q.pop()!;
1411
if (i === destination) {
1512
return true;
1613
}
17-
if (vis.has(i)) {
18-
continue;
14+
for (const j of g[i]) {
15+
if (!vis.has(j)) {
16+
vis.add(j);
17+
q.push(j);
18+
}
1919
}
20-
vis.add(i);
21-
q.push(...g[i]);
2220
}
23-
2421
return false;
2522
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
1-
class Solution {
1+
class UnionFind {
22
public:
3-
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
4-
vector<int> p(n);
3+
UnionFind(int n) {
4+
p = vector<int>(n);
5+
size = vector<int>(n, 1);
56
iota(p.begin(), p.end(), 0);
6-
function<int(int)> find = [&](int x) -> int {
7-
if (p[x] != x) {
8-
p[x] = find(p[x]);
7+
}
8+
9+
void unite(int a, int b) {
10+
int pa = find(a), pb = find(b);
11+
if (pa != pb) {
12+
if (size[pa] > size[pb]) {
13+
p[pb] = pa;
14+
size[pa] += size[pb];
15+
} else {
16+
p[pa] = pb;
17+
size[pb] += size[pa];
918
}
10-
return p[x];
11-
};
12-
for (auto& e : edges) {
13-
p[find(e[0])] = find(e[1]);
1419
}
15-
return find(source) == find(destination);
20+
}
21+
22+
int find(int x) {
23+
if (p[x] != x) {
24+
p[x] = find(p[x]);
25+
}
26+
return p[x];
27+
}
28+
29+
private:
30+
vector<int> p, size;
31+
};
32+
33+
class Solution {
34+
public:
35+
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
36+
UnionFind uf(n);
37+
for (const auto& e : edges) {
38+
uf.unite(e[0], e[1]);
39+
}
40+
return uf.find(source) == uf.find(destination);
1641
}
1742
};

0 commit comments

Comments
 (0)