https://leetcode.com/problems/accounts-merge/description/
class UnionFound { public: unordered_map<int,int> parents; int cnt = 0; void AddItem(int i) { parents[i] = i; cnt++; } int GetParent(int i) { if (parents[i] == i) return i; return parents[i] = GetParent(parents[i]); } void Union(int p, int c) { int pp = GetParent(p); int cp = GetParent(c); if (pp != cp) { parents[cp] = pp; cnt--; } } }; class Solution { public: vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) { UnionFound uf; for (int i = 0; i < accounts.size(); i++) uf.AddItem(i); unordered_map<string, int> map_email_to_person; for (int i = 0; i < accounts.size(); i++) for (int j = 1; j < accounts[i].size(); j++) { const auto& email = accounts[i][j]; if (map_email_to_person.count(email)) { uf.Union(map_email_to_person[email], i); } else { map_email_to_person[email] = i; } } unordered_map<int, set<string>> map_person_to_emails; for (int i = 0; i < accounts.size(); i++) { int person = uf.GetParent(i); for (int j = 1; j < accounts[i].size(); j++) { const auto& email = accounts[i][j]; map_person_to_emails[person].insert(email); } } vector<vector<string>> res; for (const auto& it : map_person_to_emails) { vector<string> p; p.push_back(accounts[it.first][0]); for (const auto & email : it.second) p.push_back(email); res.push_back(p); } return res; } };