Accounts Merge

Merge user accounts sharing any email — Union-Find over emails.

Medium
Time O(N * L * α) Space O(N * L)
LeetCode
5 min read
union-find hash-map strings

Problem#

Given a list of accounts where accounts[i] = [name, email1, email2, ...], merge accounts that share any email. Two accounts belong to the same person if they share at least one email. Each merged account: name first, then sorted unique emails.

Examples#

  • accounts = [["John","johnsmith@mail.com","john_newyork@mail.com"],["John","johnsmith@mail.com","john00@mail.com"],["Mary","mary@mail.com"],["John","johnnybravo@mail.com"]] → 3 accounts merging the first two.

Constraints#

  • 1 <= accounts.length <= 1000, 2 <= accounts[i].length <= 10.

Hints#

Hint
Map each email to its first-seen account index; union accounts that share emails.

Approach#

DSU over account indices. Walk each account; for each email, either claim it for this account (emailOwner[e] = i) or union this account with the existing owner. Then bucket all emails by their account’s root and sort within each bucket.

Solution#

Accounts Merge
class Solution {
vector<int> parent;
int find(int x) { while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } return x; }
void unite(int a, int b) { parent[find(a)] = find(b); }
public:
vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {
int n = accounts.size();
parent.resize(n);
iota(parent.begin(), parent.end(), 0);
unordered_map<string,int> owner;
for (int i = 0; i < n; ++i) {
for (int j = 1; j < (int)accounts[i].size(); ++j) {
auto it = owner.find(accounts[i][j]);
if (it == owner.end()) owner[accounts[i][j]] = i;
else unite(i, it->second);
}
}
unordered_map<int, set<string>> byRoot;
for (auto& [e, i] : owner) byRoot[find(i)].insert(e);
vector<vector<string>> ans;
for (auto& [root, emails] : byRoot) {
vector<string> row;
row.push_back(accounts[root][0]);
row.insert(row.end(), emails.begin(), emails.end());
ans.push_back(std::move(row));
}
return ans;
}
};

Editorial#

The DSU lives over account indices, not emails — so each account stays anchored to its name. Emails act as edges between accounts (any shared email unions both sides). Using set<string> per root gives deduplication + sortedness for free.

Complexity#

  • Time: O(E * α(N) + E log E).
  • Space: O(E).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.