|
1 |
| -class Solution: |
2 |
| -def validTree(self, n: int, edges: List[List[int]]) -> bool: |
3 |
| -if len(edges) != n - 1 : |
4 |
| -return False |
| 1 | +Notes |
5 | 2 |
|
6 |
| - # Create edge map |
7 |
| - e = defaultdict(set) |
8 |
| - for u, v in edges : |
9 |
| - e[u].add(v) |
10 |
| - e[v].add(u) |
| 3 | +- For a tree to be valid, $|E|=|V|-1$ must be true where $E$ is the edge set and $V$ is the vertex set |
| 4 | +- Check for cycle starting from a random node -- track visited nodes |
| 5 | + - If any cycle is found, we return False |
| 6 | + - If no cycle is found, we continue |
| 7 | +- Check if all nodes were visited |
| 8 | + - If all nodes visited, we return True |
| 9 | + - Else, we return False |
11 | 10 |
|
12 |
| - # Detect cycle to save runtime -- breaks out early if cycle detected otherwise attempts |
13 |
| - # to validate by visiting all n edges |
14 |
| - def dfs_detect_cycle(curr: int, prev: int, e: defaultdict, visited: Set[int]) -> bool : |
15 |
| - if curr in visited : |
16 |
| - return True |
17 |
| - visited.add(curr) |
18 |
| - if any(dfs_detect_cycle(nxt, curr, e, visited) for nxt in e[curr] if nxt != prev) : |
19 |
| - return (True, visited) |
20 |
| - return False |
| 11 | +In theory the all nodes visited check is all that we need as long as avoid infinite looping in cycles. However, it's more efficient if we break out early if a cycle is found. |
21 | 12 |
|
22 |
| - # Since dfs_detect_cycle() is called first before the or, visited() will be |
23 |
| - # filled prior to len() being tested |
24 |
| - visited = set() |
25 |
| - if dfs_detect_cycle(1, None, e, visited) or not len(visited) == n : |
26 |
| - return False |
| 13 | +The reason for the all nodes visited check after cycles is for graphs such as this: |
27 | 14 |
|
28 |
| - return True |
| 15 | +``` |
| 16 | + 1 2 |
| 17 | + | / \ |
| 18 | + 3 4---5 |
| 19 | +``` |
| 20 | + |
| 21 | +This graph has 5 vertices and 4 edges which fulfills the first condition. It's possible we'll start our cycle check on vertex 1 wherein we won't have a cycle, but there's a cycle elsewhere. |
0 commit comments