Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
440 changes: 304 additions & 136 deletions solution/1900-1999/1971.Find if Path Exists in Graph/README.md

Large diffs are not rendered by default.

442 changes: 305 additions & 137 deletions solution/1900-1999/1971.Find if Path Exists in Graph/README_EN.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
class Solution {
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
vector<bool> vis(n);
vector<int> g[n];
for (auto& e : edges) {
int a = e[0], b = e[1];
g[a].emplace_back(b);
g[b].emplace_back(a);
vector<bool> vis(n);
for (const auto& e : edges) {
int u = e[0], v = e[1];
g[u].push_back(v);
g[v].push_back(u);
}
function<bool(int)> dfs = [&](int i) -> bool {
if (i == destination) {
return true;
}
vis[i] = true;
for (int& j : g[i]) {
for (int j : g[i]) {
if (!vis[j] && dfs(j)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ func validPath(n int, edges [][]int, source int, destination int) bool {
vis := make([]bool, n)
g := make([][]int, n)
for _, e := range edges {
a, b := e[0], e[1]
g[a] = append(g[a], b)
g[b] = append(g[b], a)
u, v := e[0], e[1]
g[u] = append(g[u], v)
g[v] = append(g[v], u)
}
var dfs func(int) bool
dfs = func(i int) bool {
Expand All @@ -20,4 +20,4 @@ func validPath(n int, edges [][]int, source int, destination int) bool {
return false
}
return dfs(source)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ class Solution {
private List<Integer>[] g;

public boolean validPath(int n, int[][] edges, int source, int destination) {
this.destination = destination;
vis = new boolean[n];
g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
Arrays.setAll(g, i -> new ArrayList<>());
for (var e : edges) {
int a = e[0], b = e[1];
g[a].add(b);
g[b].add(a);
int u = e[0], v = e[1];
g[u].add(v);
g[v].add(u);
}
vis = new boolean[n];
this.destination = destination;
return dfs(source);
}

Expand All @@ -21,7 +21,7 @@ private boolean dfs(int i) {
return true;
}
vis[i] = true;
for (int j : g[i]) {
for (var j : g[i]) {
if (!vis[j] && dfs(j)) {
return true;
}
Expand Down
16 changes: 7 additions & 9 deletions solution/1900-1999/1971.Find if Path Exists in Graph/Solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ class Solution:
def validPath(
self, n: int, edges: List[List[int]], source: int, destination: int
) -> bool:
def dfs(i):
def dfs(i: int) -> bool:
if i == destination:
return True
vis.add(i)
for j in g[i]:
if j not in vis and dfs(j):
return True
return False
if i in vis:
return False
return any(dfs(j) for j in g[i])

g = [[] for _ in range(n)]
for a, b in edges:
g[a].append(b)
g[b].append(a)
for u, v in edges:
g[u].append(v)
g[v].append(u)
vis = set()
return dfs(source)
44 changes: 24 additions & 20 deletions solution/1900-1999/1971.Find if Path Exists in Graph/Solution.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
impl Solution {
pub fn valid_path(n: i32, edges: Vec<Vec<i32>>, source: i32, destination: i32) -> bool {
let mut disjoint_set: Vec<i32> = vec![0; n as usize];
// Initialize the set
for i in 0..n {
disjoint_set[i as usize] = i;
}

// Traverse the edges
for p_vec in &edges {
let parent_one = Solution::find(p_vec[0], &mut disjoint_set);
let parent_two = Solution::find(p_vec[1], &mut disjoint_set);
disjoint_set[parent_one as usize] = parent_two;
}
let n = n as usize;
let source = source as usize;
let destination = destination as usize;

let p_s = Solution::find(source, &mut disjoint_set);
let p_d = Solution::find(destination, &mut disjoint_set);
let mut g = vec![Vec::new(); n];
let mut vis = vec![false; n];

p_s == p_d
}
for e in edges {
let u = e[0] as usize;
let v = e[1] as usize;
g[u].push(v);
g[v].push(u);
}

pub fn find(x: i32, d_set: &mut Vec<i32>) -> i32 {
if d_set[x as usize] != x {
d_set[x as usize] = Solution::find(d_set[x as usize], d_set);
fn dfs(g: &Vec<Vec<usize>>, vis: &mut Vec<bool>, i: usize, destination: usize) -> bool {
if i == destination {
return true;
}
vis[i] = true;
for &j in &g[i] {
if !vis[j] && dfs(g, vis, j, destination) {
return true;
}
}
false
}
d_set[x as usize]

dfs(&g, &mut vis, source, destination)
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
function validPath(n: number, edges: number[][], source: number, destination: number): boolean {
const g: number[][] = Array.from({ length: n }, () => []);
for (const [a, b] of edges) {
g[a].push(b);
g[b].push(a);
for (const [u, v] of edges) {
g[u].push(v);
g[v].push(u);
}

const vis = new Set<number>();
const dfs = (i: number) => {
if (i === destination) {
Expand All @@ -13,10 +12,8 @@ function validPath(n: number, edges: number[][], source: number, destination: nu
if (vis.has(i)) {
return false;
}

vis.add(i);
return g[i].some(dfs);
};

return dfs(source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ class Solution {
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
vector<vector<int>> g(n);
for (auto& e : edges) {
int a = e[0], b = e[1];
g[a].push_back(b);
g[b].push_back(a);
for (const auto& e : edges) {
int u = e[0], v = e[1];
g[u].push_back(v);
g[v].push_back(u);
}
queue<int> q{{source}};
vector<bool> vis(n);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
func validPath(n int, edges [][]int, source int, destination int) bool {
g := make([][]int, n)
for _, e := range edges {
a, b := e[0], e[1]
g[a] = append(g[a], b)
g[b] = append(g[b], a)
u, v := e[0], e[1]
g[u] = append(g[u], v)
g[v] = append(g[v], u)
}
q := []int{source}
vis := make([]bool, n)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ public boolean validPath(int n, int[][] edges, int source, int destination) {
List<Integer>[] g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
for (var e : edges) {
int a = e[0], b = e[1];
g[a].add(b);
g[b].add(a);
int u = e[0], v = e[1];
g[u].add(v);
g[v].add(u);
}
Deque<Integer> q = new ArrayDeque<>();
q.offer(source);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ def validPath(
self, n: int, edges: List[List[int]], source: int, destination: int
) -> bool:
g = [[] for _ in range(n)]
for a, b in edges:
g[a].append(b)
g[b].append(a)

for u, v in edges:
g[u].append(v)
g[v].append(u)
q = deque([source])
vis = {source}
while q:
Expand Down
28 changes: 16 additions & 12 deletions solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@ use std::collections::{HashSet, VecDeque};

impl Solution {
pub fn valid_path(n: i32, edges: Vec<Vec<i32>>, source: i32, destination: i32) -> bool {
let mut g = vec![HashSet::new(); n as usize];
for e in edges {
let a = e[0] as usize;
let b = e[1] as usize;
g[a].insert(b);
g[b].insert(a);
let n = n as usize;
let source = source as usize;
let destination = destination as usize;

let mut g = vec![Vec::new(); n];
for edge in edges {
let u = edge[0] as usize;
let v = edge[1] as usize;
g[u].push(v);
g[v].push(u);
}

let mut q = VecDeque::new();
q.push_back(source as usize);
let mut vis = vec![false; n as usize];
vis[source as usize] = true;
let mut vis = HashSet::new();
q.push_back(source);
vis.insert(source);

while let Some(i) = q.pop_front() {
if i == (destination as usize) {
if i == destination {
return true;
}
for &j in &g[i] {
if !vis[j] {
vis[j] = true;
if !vis.contains(&j) {
vis.insert(j);
q.push_back(j);
}
}
Expand Down
21 changes: 9 additions & 12 deletions solution/1900-1999/1971.Find if Path Exists in Graph/Solution2.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
function validPath(n: number, edges: number[][], source: number, destination: number): boolean {
const g: number[][] = Array.from({ length: n }, () => []);

for (const [a, b] of edges) {
g[a].push(b);
g[b].push(a);
for (const [u, v] of edges) {
g[u].push(v);
g[v].push(u);
}

const vis = new Set<number>();
const vis = new Set<number>([source]);
const q = [source];

while (q.length) {
const i = q.pop()!;
if (i === destination) {
return true;
}
if (vis.has(i)) {
continue;
for (const j of g[i]) {
if (!vis.has(j)) {
vis.add(j);
q.push(j);
}
}
vis.add(i);
q.push(...g[i]);
}

return false;
}
47 changes: 36 additions & 11 deletions solution/1900-1999/1971.Find if Path Exists in Graph/Solution3.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
class Solution {
class UnionFind {
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
vector<int> p(n);
UnionFind(int n) {
p = vector<int>(n);
size = vector<int>(n, 1);
iota(p.begin(), p.end(), 0);
function<int(int)> find = [&](int x) -> int {
if (p[x] != x) {
p[x] = find(p[x]);
}

void unite(int a, int b) {
int pa = find(a), pb = find(b);
if (pa != pb) {
if (size[pa] > size[pb]) {
p[pb] = pa;
size[pa] += size[pb];
} else {
p[pa] = pb;
size[pb] += size[pa];
}
return p[x];
};
for (auto& e : edges) {
p[find(e[0])] = find(e[1]);
}
return find(source) == find(destination);
}

int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}

private:
vector<int> p, size;
};

class Solution {
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
UnionFind uf(n);
for (const auto& e : edges) {
uf.unite(e[0], e[1]);
}
return uf.find(source) == uf.find(destination);
}
};
Loading
Loading