Teaching Kids Programming – Find if Path Exists in Graph via Depth First Search Algorithm


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.

graph-data-structure Teaching Kids Programming - Find if Path Exists in Graph via Depth First Search Algorithm algorithms DFS python recursive teaching kids programming youtube video

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) —

GD Star Rating
loading...
675 words
Last Post: How to improve your security when gambling online?
Next Post: Teaching Kids Programming - Anagram Substrings via Sliding Window

The Permanent URL is: Teaching Kids Programming – Find if Path Exists in Graph via Depth First Search Algorithm

Leave a Reply