Accounts Merge – Solution & Complexity

Solution Walkthrough

1. See the connectivity pattern

  • If two rows share an email, they belong to the same connected component.
  • The overlap can be indirect, so you need component merging rather than only pairwise merging.

2. Brute-force baseline

  • Compare every pair of rows to see whether they share any email, then repeatedly merge overlapping groups.
  • That repeated scanning is much too slow once many accounts and emails exist.

3. Union rows by shared emails

  • Map each email to the first row that contained it.
  • When the same email appears again, union the current row with the previous owner row.

4. Final solution (all languages)

Union-find builds connected account components, then a deterministic sort finishes the output contract.

def accounts_merge(accounts: list[list[str]]) -> list[list[str]]:
    parent = list(range(len(accounts)))
    rank = [0] * len(accounts)

    def find(node: int) -> int:
        while node != parent[node]:
            parent[node] = parent[parent[node]]
            node = parent[node]
        return node

    def union(a: int, b: int) -> None:
        root_a = find(a)
        root_b = find(b)
        if root_a == root_b:
            return
        if rank[root_a] < rank[root_b]:
            root_a, root_b = root_b, root_a
        parent[root_b] = root_a
        if rank[root_a] == rank[root_b]:
            rank[root_a] += 1

    email_owner: dict[str, int] = {}
    for index, account in enumerate(accounts):
        for email in account[1:]:
            if email in email_owner:
                union(index, email_owner[email])
            else:
                email_owner[email] = index

    grouped: dict[int, list[str]] = {}
    for email in email_owner:
        root = find(email_owner[email])
        grouped.setdefault(root, []).append(email)

    merged: list[list[str]] = []
    for root, emails in grouped.items():
        emails.sort()
        merged.append([accounts[root][0], *emails])

    merged.sort(key=lambda row: (row[0], row[1]))
    return merged

5. Complexity summary

  • Union-find work is effectively near-linear in the number of email occurrences.
  • Sorting the merged email lists dominates the final deterministic formatting cost.

FAQ