LeetCode 684: Redundant Connection

link

Union-find

With n nodes we start building the tree. If we find two ends of an edge already connected, that edge is redundant.

OperationTimeSpace
UnionFind(n)\mathcal{O}(n)\mathcal{O}(n)
is_connected\mathcal{O}(\lg^*{n})\mathcal{O}(1)
connect\mathcal{O}(\lg^*{n})\mathcal{O}(1)
class UnionFind:
    def __init__(self, n):
        self.parent_of = {u: u for u in range(1, n+1)}
        self.rank_of = {u: 0 for u in range(1, n+1)}

    def __compress_path(self, u, root):
        while u != (p := self.parent_of[u]):
            self.parent_of[u] = root
            u = p

    def __find(self, u):
        root = u
        while root != (p := self.parent_of[root]):
            root = p
        self.__compress_path(u, root)
        
        return root

    def is_connected(self, u, v):
        root_u = self.__find(u)
        root_v = self.__find(v)
        
        return root_u == root_v

    def connect(self, u, v):
        root_u = self.__find(u)
        root_v = self.__find(v)

        rank_u = self.rank_of[root_u]
        rank_v = self.rank_of[root_v]
        if rank_u == rank_v:
            self.parent_of[root_u] = root_v
            self.rank_of[root_v] += 1
            return
        
        if rank_u > rank_v:
            self.parent_of[root_v] = root_u
        else:
            self.parent_of[root_u] = root_v

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        n = len(edges)
        uf = UnionFind(n)
        redundant = None
        for e in edges:
            u, v = e
            if uf.is_connected(u, v):
                redundant = e
            else:
                uf.connect(u, v)
        
        return redundant

Leave a comment