Teaching Kids Programming: Videos on Data Structures and Algorithms
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 start to vertex end.
Given edges and the integers n, start, and end, return true if there is a valid path from start to end, or false otherwise.
Example 1:
Input: n = 3, edges = [[0,1],[1,2],[2,0]], start = 0, end = 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]], start = 0, end = 5
Output: false
Explanation: There is no path from vertex 0 to vertex 5.There are no duplicate edges.
There are no self edges.
Graph Algorithm: Depth First Search to Check Connectivity between Vertices
First, we build the Graph from the list of edges using an Adjacent Linked List. Then, we need to use a hash set to remember the vertices that we have seen/visited so that we don’t end up in endless cycles.
The DFS is implemented in Recursion – from the start, we recursively check if there is a path between its direct connected vertices to destination.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Solution: def validPath(self, n: int, edges: List[List[int]], start: int, end: int) -> bool: G = defaultdict(list[int]) for s,e in edges: G[s].append(e) G[e].append(s) seen = set() @cache def dfs(s, e): if s == e: return True seen.add(s) for i in G[s]: if i not in seen and dfs(i, e): return True return False return dfs(start, end) |
class Solution: def validPath(self, n: int, edges: List[List[int]], start: int, end: int) -> bool: G = defaultdict(list[int]) for s,e in edges: G[s].append(e) G[e].append(s) seen = set() @cache def dfs(s, e): if s == e: return True seen.add(s) for i in G[s]: if i not in seen and dfs(i, e): return True return False return dfs(start, end)
We can also add @cache to memoize the results. Alternatively, we can use the dictionary/hash set to manually remember the values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Solution: def validPath(self, n: int, edges: List[List[int]], start: int, end: int) -> bool: G = defaultdict(list[int]) for s,e in edges: G[s].append(e) G[e].append(s) seen = set() memo = defaultdict(bool) def dfs(s, e): if s == e: return True if (s, e) in memo: return memo[(s, e)] seen.add(s) for i in G[s]: if i not in seen and dfs(i, e): memo[(s, e)] = True return True memo[(s, e)] = False return False return dfs(start, end) |
class Solution: def validPath(self, n: int, edges: List[List[int]], start: int, end: int) -> bool: G = defaultdict(list[int]) for s,e in edges: G[s].append(e) G[e].append(s) seen = set() memo = defaultdict(bool) def dfs(s, e): if s == e: return True if (s, e) in memo: return memo[(s, e)] seen.add(s) for i in G[s]: if i not in seen and dfs(i, e): memo[(s, e)] = True return True memo[(s, e)] = False return False return dfs(start, end)
See also: Teaching Kids Programming – Find if Path Exists in Graph via Breadth First Search Algorithm
We can also solve this problem by using Union Find + Disjoint Set Algorithm: Teaching Kids Programming – Disjoint Set: Find if Path Exists in Graph via Union Find Algorithm
–EOF (The Ultimate Computing & Technology Blog) —
loading...
Last Post: How to improve your security when gambling online?
Next Post: Teaching Kids Programming - Anagram Substrings via Sliding Window