Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
Input: n =5, and edges =[[0,1],[0,2],[0,3],[1,4]]Output: true
Example 2:
1
2
Input: n =5, and edges =[[0,1],[1,2],[2,3],[1,3],[1,4]]Output: false
Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0,1] is the same as [1,0] and thus will not appear together in edges.
In an undirected graph, visiting a child node often includes revisiting its parent, leading to a trivial cycle rather than a genuine one. This can be avoided by passing a parent state in the DFS call to distinguish valid backtracking. Additionally, if the number of visited nodes equals the total nodes in the graph, it ensures the graph is connected.
classSolution:
def validTree(self, n: int, edges: List[List[int]]) -> bool:
if len(edges) != n - 1:
return False
# Constructing adjacency list
graph = {i: []for i in range(n)}
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
visited = set()
def dfs(node: int, parent: int) -> bool:
if node in visited:
return False
visited.add(node)
for nbr in graph[node]:
if nbr != parent:
if not dfs(nbr, node):
return False
return True
# Check for cycles
if not dfs(0, -1):
return False
# Check for connectivity
returnlen(visited) == n
No Cycles: During the traversal, if we encounter a node that has already been visited (and is not the parent of the current node), then we have a cycle.
Connectivity: After traversal, all nodes must have been visited to confirm connectivity.
classSolution:
defvalidTree(self, n: int, edges: List[List[int]]) -> bool:
if len(edges) != n -1:
returnFalse# Construct adjacency list graph = {i: [] for i in range(n)}
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
visited = set()
queue: Deque[(int, int)] = deque([(0, -1)]) # (node, parent)while queue:
node, parent = queue.popleft()
if node in visited:
returnFalse visited.add(node)
for nbr in graph[node]:
if nbr != parent: # Avoid revisiting the parent queue.append((nbr, node))
# Check for connectivityreturn len(visited) == n