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. hdu 3863 No Gambling (不会证明,但是是对的,,)

    题意: N=4时 规则: 双方每次可以连接自己颜色的两个点(相邻,长度为1),线和线不能交叉重叠. 蓝方要连接左右,红方要连接上下. 蓝方先.问谁先连接? 思路: 经过观察....蓝方胜....... ...

  2. Android Jetpack Compose 引入示例工程

    引入 Jetpack Compose 示例工程 去GitHub上找到Compose的示例工程 https://github.com/android/compose-samples ,clone到本地 ...

  3. Centos 8 升级ssl到1.1.1h

    升级到1.1.1h版本 #编译openssl和安装 ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl & ...

  4. C语言的“隐式函数声明”违背了 “前置声明” 原则

    这个问题来源于小组交流群里的一个问题: 最终问题落脚在 : 一个函数在main中调用了,必须在main之前定义或者声明吗? 我在自己的Centos上做了实验,结果是函数不需要,但是结构体(变量也要)需 ...

  5. Jmeter二次开发实现自定义functions函数(九)

    在Jmeter->选项->函数助手对话框中我们可以看到Jmeter内置的一些常用函数,但考虑到测试过程中的实际情况,我们经常需要在脚本引用或者实现自定义的函数.那么如何在"函数助 ...

  6. [linux]centos7.4部署django+Uwsgi+Nginx

    前言:我已经写了几个接口用来部署在服务器上的,首先选择django+Uwsgi+Nginx因为配置简单,比较符合python的简单操作功能强大的特点 然后对于django的一些版本在之前的文章写了 参 ...

  7. Python MySSH 实现剧本执行器

    通过封装Paramiko这个SSH模块,我们可以实现远程批量管理Linux主机,在上一篇文章中我们封装过一个MySSH类,这个类可以执行命令上传下载文件等,我们在这个类的基础上,实现一个简单的任务执行 ...

  8. 升级npm后版本依然没有变 原来是全局npm设置的锅

    最近准备给家里的老爷机打一个 react 的环境 win7系统还不算老~ 不过!由于很多年以前装的node了版本很低,所以赶紧去官网 下了一个 最新的稳定版本的. 卸载和安装都费了老大力了. 以为光明 ...

  9. [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处

    前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...

  10. 关于新手使用mpb开发代码的一些小知识

    mac 前端端口占用解决   1.查看8080端口,复制进程PID  lsof -i :8080 2.杀死进程 kill -9 「进程PID」   如果你的mac不能使用sudo解决办法   错误提示 ...