Redundant Connections with Union Find
The Union Find algorithm is used to group similar times in a graph and is popular in social networking. We create a union based on the relationship between the entities.
2 | image | |
Template for Union Find | 1 | heading |
| 2 | list |
import collections
def UnionFind(edges):
parent = collections.defaultdict()
group = collections.defaultdict(set)
def find(x):
# x is not present then assign x is its own parent
if x not in parent:
parent[x] = x
#find parent's parents untill parent has no parent other than itelf
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
#find parent of x and y
parent_x = find(x)
parent_y = find(y)
#assign parent of x to y
parent[parent_y] = parent_x
#group x and y together
group[parent_x].add(x)
group[parent_x].add(y)
for x , y in edges:
union(x,y)
return list(group.values()) #[{'B', 'F', 'A', 'C'}, {'E', 'D'}] | 3 | code |
Redundant Connection | 4 | heading |
684. Redundant Connection | 5 | link |
In this problem, a tree is an undirected graph that is connected and has no cycles. You are given a graph that started as a tree with n nodes labeled from 1 to n, with one additional edge added. The added edge has two different vertices chosen from 1 to n, and was not an edge that already existed. The graph is represented as an array edges of length n where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the graph. Return an edge that can be removed so that the resulting graph is a tree of n nodes. If there are multiple answers, return the answer that occurs last in the input. | 6 | paragraph |
Promoted Promoted | 7 | image |
Input: edges = [[1,2],[2,3],[3,4],[1,4],[1,5]]
Output: [1,4] | 8 | code |
Intuition | 9 | subheading |
| 10 | list |
def findRedundantConnection(edges):
parent = collections.defaultdict()
rank = collections.defaultdict(int)
def find(x):
# x is not present then assign x is its own parent
#initial rank 0
if x not in parent:
parent[x] = x
rank[x] = 0
#find parent's parents untill parent has no parent other than itelf
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
#find parent of x and y
parent_x = find(x)
parent_y = find(y)
#check if parents are same
if parent_x == parent_y:
return False
#assign parent with higher ranking
if rank[parent_x] < rank[parent_y]:
parent[parent_x] = parent_y
else:
parent[parent_y] = parent_x
if rank[parent_x] == rank[parent_y]:
rank[parent_x] += 1
return True
for x, y in edges:
if not union(x, y):
return [x, y] | 11 | code |
Redundant Connection II | 12 | heading |
685. Redundant Connection II | 13 | link |
Promoted Promoted In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents. The given input is a directed graph that started as a rooted tree with n nodes (with distinct values from 1 to n), with one additional directed edge added. The added edge has two different vertices chosen from 1 to n, and was not an edge that already existed. The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [ui, vi] that represents a directed edge connecting nodes ui and vi, where ui is a parent of child vi. Return an edge that can be removed so that the resulting graph is a rooted tree of n nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. | 14 | paragraph |
Input: edges = [[1,2],[2,3],[3,4],[4,1],[1,5]]
Output: [4,1] | 15 | code |
16 | image | |
Intuition | 17 | subheading |
| 18 | list |
def findRedundantDirectedConnection(edges):
parent = collections.defaultdict()
rank = collections.defaultdict(int)
def find(x):
# x is not present then assign x is its own parent
#initial rank 0
if x not in parent:
parent[x] = x
rank[x] = 0
#find parent's parents untill parent has no parent other than itelf
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
#find parent of x and y
parent_x = find(x)
parent_y = find(y)
#check if parents are same
if parent_x == parent_y:
return False
#assign parent with higher ranking
if rank[parent_x] < rank[parent_y]:
parent[parent_x] = parent_y
else:
parent[parent_y] = parent_x
if rank[parent_x] == rank[parent_y]:
rank[parent_x] += 1
return True
parent1 = None
parent2 = None
point_to = {}
for x, y in edges:
if y in point_to:
#we found y with 2 parents
parent1 = point_to[y]
parent2 = [x, y]
break
point_to[y] = [x, y]
#print(cand1, cand2, point_to)
for x, y in edges:
if [x, y] == parent2: continue
if not union(x-1, y-1):
if parent1: return parent1 #case III
return [x, y] #case II
return parent2 #case I | 19 | code |