原题地址(中等)
方法1—并查集+哈希表
思路
见力扣题解,写的真的好棒~
代码
// 并查集模板class UnionFind {public:vector<int> parent;vector<int> rank;public:UnionFind(int _n): parent(vector<int>(_n)), rank(vector<int>(_n)) {for(int i=0; i<_n; i++)parent[i] = i;}int find(int x) {if(x != parent[x]) {parent[x] = find(parent[x]); // 路径压缩}return parent[x];}void merge(int x, int y) { // 按秩合并int rootx = find(x);int rooty = find(y);if(rootx != rooty) {if(rank[rootx] < rank[rooty]) swap(rootx, rooty);parent[rooty] = rootx;if(rank[rootx] == rank[rooty]) rank[rootx]++;}}};class Solution {public:vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {vector<vector<string> > res;// 作用:存储每个邮箱属于哪个账户 ,同时 在遍历邮箱时,判断邮箱是否出现过// 格式:<邮箱,账户id>unordered_map<string, int> um;int n = accounts.size();UnionFind uf(n);for(int i = 0; i < n; i++) {int m = accounts[i].size();// 对每个邮箱,如果还未出现过,就放到哈希表中,否则将该账户与已经出现过该邮箱的账户合并for(int j = 1; j < m; j++) {string s = accounts[i][j];if(um.find(s) == um.end()) um[s] = i;else uf.merge(i, um[s]);}}// 作用: 存储每个账户下的邮箱// 格式: <账户id, 邮箱列表> >// 注意:umv的key必须是账户id,不能是账户名称,名称可能相同,会造成覆盖unordered_map<int, vector<string>> umv;for(auto& [k, v] : um) umv[uf.find(v)].emplace_back(k);for(auto& [k, v] : umv) {sort(v.begin(), v.end());vector<string> tmp(1, accounts[k][0]); // 名字tmp.insert(tmp.end(), v.begin(), v.end());res.emplace_back(tmp);}return res;}};
