Given a list of accounts where each element accounts[i] is a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements are emails representing emails of the account.

Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some common email to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name.

After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order.

Example 1:

Input: accounts = [["John","johnsmith@mail.com","john_newyork@mail.com"],["John","johnsmith@mail.com","john00@mail.com"],["Mary","mary@mail.com"],["John","johnnybravo@mail.com"]]
Output: [["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"],["Mary","mary@mail.com"],["John","johnnybravo@mail.com"]]
Explanation:
The first and second John's are the same person as they have the common email "johnsmith@mail.com".
The third John and Mary are different people as none of their email addresses are used by other accounts.
We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'],
['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.

这道题的需求是账户合并,accounts 中每个数组中第一个元素是用户名,后面是其邮箱,最终需要合并求出一个用户下所有的邮箱,这里要注意以下,相同的用户名所属的邮箱不一定合并,除非其用户名下有相同的邮箱。
有一种初略的合并方法,先用set存储一个用户的所有邮箱,然后遍历另外一个同名用户中所有的邮箱,如果在之前用户存储邮箱数组中find到,那么就insert到前一个set中,但是这样会存在一个问题。即

  结果发现对于下面这个例子不适用:

  ["John", "a@gmail.com", "b@gmail.com"]

  ["John", "c@gmail.com", "d@gmail.com"]

  ["John", "a@gmail.com", "c@gmail.com"]

  如果按照遍历顺序不同,第二组的邮箱并不会加入到“John”中,也就是上述融合思路无法传递依赖,对于这种分组问题,还是优先用并查集来做,先分好组,每个邮箱指向一个根邮箱,然后根据根邮箱来找用户,存储下来。所以按照这种思路,那么我们需要构建如下几个数据结构,root 用于映射根邮箱,owner用于邮箱与用户的映射,还需要一个map 来去重的存储根邮箱以及同一组邮箱。根据上述分析代码如下:

class Solution {
public:
vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {
// 用什么数据结构最方便的存储这些数据
// 用map 记录用户与 邮箱的映射 邮箱用set 存储去重?
// 重点是用什么样的数据结构对上述accounts进行存储 分组
// 涉及到分组问题 可以考虑用union find进行分组
vector<vector<string>> res;
unordered_map<string,string> root;// 每个邮箱指向的根
unordered_map<string,string> owner;// 每个邮箱指向的用户
unordered_map<string,set<string>>mm;// 一个根邮箱对应的一组相关联的邮箱
// 初始化并查集的root
for(auto account:accounts){
for(int i=1;i<account.size();++i){
// 第一个元素是用户名
root[account[i]]=account[i];// 每个邮箱开始都指向自己
owner[account[i]]=account[0];
}
}
// 同组邮箱分类
for(auto account:accounts){
string p=find(account[1],root);
for(int i=2;i<account.size();++i){
root[find(account[i],root)]=p;//union find 更新根节点
}
}
// 同一组邮箱汇总
for(auto account:accounts){
for(int i=1;i<account.size();++i){
mm[find(account[i],root)].insert(account[i]);
}
}
//将同组邮箱 根据根节点映射寻找owner
for(auto m:mm){
vector<string> vv(m.second.begin(),m.second.end());
vv.insert(vv.begin(),owner[m.first]);//在数组开头插入用户名
res.push_back(vv);
}
return res;
}
string find(string s,unordered_map<string,string> &root){
return s==root[s]?s:(root[s]=find(root[s],root));// 压缩路径并返回每个邮箱映射的根节点
}
};




【leetcode】721. Accounts Merge(账户合并)的更多相关文章

  1. [LeetCode] 721. Accounts Merge 账户合并

    Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...

  2. [leetcode]721. Accounts Merge账户合并

    Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...

  3. [LeetCode] Accounts Merge 账户合并

    Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...

  4. LeetCode 721. Accounts Merge

    原题链接在这里:https://leetcode.com/problems/accounts-merge/ 题目: Given a list accounts, each element accoun ...

  5. 【LeetCode】721. Accounts Merge 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/accounts ...

  6. 721. Accounts Merge合并电子邮件账户

    [抄题]: Given a list accounts, each element accounts[i] is a list of strings, where the first element  ...

  7. Leetcode(712)-账户合并

    给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址 ...

  8. [LeetCode] 721. Accounts Merge_Medium tag: DFS recursive

    Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...

  9. 721. Accounts Merge

    https://leetcode.com/problems/accounts-merge/description/ class UnionFound { public: unordered_map&l ...

随机推荐

  1. 第07课 OpenGL 光照和键盘(2)

    下一段代码绘制贴图立方体.我只对新增的代码进行注解.如果您对没有注解的代码有疑问,回头看看第六课. int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制 { glClear( ...

  2. 五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

    系列文章 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的 ...

  3. Xshell Error Report,Program has stopped working

    xftp和xshell突然都无法运行并报错如图 图中的意思是,xshell有错误,官方想收集错误.可是也不能给你发送了,还这样啊. 解决办法 1.卸载Xshell和Xftp,重新安装. 参考:http ...

  4. spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小

    背景 最近小伙伴解决了一个工单,描述为"手工推送案件无法推,提示token失效",当前工单状态为待关闭,解决方案为"东软接口不稳定造成的,东软的接口恢复正常后,问题解决& ...

  5. 微信小程序(五)

    JavaScript: JavaScript 是一种轻量的,解释型的,面对对象的头等函数语言,是一种动态的基于原型和多范式的脚本语言,支持面向对象,命令式和函数式的编程风格. Nodejs 中的Jav ...

  6. node对象

    global,node的全局对象;js在游览器中的全局对象为windows 在node环境中;输入global.consloe 输出: Console { log: [Function: bound ...

  7. R数据分析:跟随top期刊手把手教你做一个临床预测模型

    临床预测模型也是大家比较感兴趣的,今天就带着大家看一篇临床预测模型的文章,并且用一个例子给大家过一遍做法. 这篇文章来自护理领域顶级期刊的文章,文章名在下面 Ballesta-Castillejos ...

  8. [EntityFramework]记录Linq中如何比较数据库中Timestamp列的方法(如大于0x00000000000007D1的记录)

    Timestamp对于EF实体的类型是byte[] class Program { static void Main(string[] args) { using (var context = new ...

  9. [noi37]列队

    直接统计答案,令dp[i][j]表示前i个数最长的颜色各不相同后缀长度为j的方案数,如果一直令j<m,那么就相当于统计了方案数. 如何推出dp[i][j]呢?考虑i-1的最长前缀是多少:当小于j ...

  10. HDC技术分论坛:HarmonyOS新一代UI框架的全面解读

    作者:yuzhiqiang,UI编程框架首席技术专家 在Harmony 3.0.0开发者预览版中,包含了新一代的声明式UI框架ArkUI 3.0.多语言跨平台编译器ArkCompiler 3.0.跨端 ...