You have a graph of n nodes labeled from 0 to n - 1. You are given an integer n and a list of edges where edges[i] = [ai, bi] indicates that there is an undirected edge between nodes ai and bi in the graph.
Return trueif the edges of the given graph make up a valid tree, andfalseotherwise.
Example 1:
1 2
Input: n = 5, edges = [[0,1],[0,2],[0,3],[1,4]] Output: true
Example 2:
1 2
Input: n = 5, edges = [[0,1],[1,2],[2,3],[1,3],[1,4]] Output: false
Solution:
If a graph does not have loop, number of edges would be number_of_vertex-1
DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defvalidTree(self, n: int, edges: List[List[int]]) -> bool: if len(edges) != n-1: returnFalse graph = defaultdict(list) for edge in edges: graph[edge[0]].append(edge[1]) graph[edge[1]].append(edge[0]) visited = set([]) defdfs(node): visited.add(node) for n in graph[node]: if n notin visited: dfs(n) dfs(0) return len(visited) == n
Union Find
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defvalidTree(self, n: int, edges: List[List[int]]) -> bool: deffind(i, vertex): if i == vertex[i]: return i else: return find(vertex[i], vertex) # union find to check if cycle exist vertex = [i for i in range(n)] for edge in edges: u, v = edge[0], edge[1] parent_u, parent_v = find(u, vertex), find(v, vertex) if parent_u == parent_v: returnFalse else: vertex[parent_u] = parent_v return len(edges) == n-1
classSolution: defvalidTree(self, n: int, edges: List[List[int]]) -> bool: queue = deque([0]) visited = set() # use set to keep all neighbors graph = defaultdict(set) for edge in edges: graph[edge[0]].add(edge[1]) graph[edge[1]].add(edge[0]) while queue: front = queue.popleft() visited.add(front) for neighbor in graph[front]: if neighbor in visited: returnFalse visited.add(neighbor) queue.append(neighbor) # remove this edge from neighbor graph[neighbor].remove(front) return len(visited) == n
time complexity: $O(V+E)$ space complexity: $O()$ reference: related problem: