Accounts Merge
Description
Given a list accounts, 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 email that is common 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
Example 1:
Input:
[
["John", "johnsmith@mail.com", "john00@mail.com"],
["John", "johnnybravo@mail.com"],
["John", "johnsmith@mail.com", "john_newyork@mail.com"],
["Mary", "mary@mail.com"]
]
Output:
[
["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],
["John", "johnnybravo@mail.com"],
["Mary", "mary@mail.com"]
]
Explanation:
The first and third John's are the same person as they have the common email "johnsmith@mail.com".
The second John and Mary are different people as none of their email addresses are used by other accounts.
You 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']
]
is also acceptable.
解题思路: 使用并查集。1. 建立 Email -> List[User] 关系。 2. 将属于同一Email的user 使用并查集连接。 3. 建立User -> List[Email] 4. 根据并查集 找到每个User的老大哥,以老大哥为代表输出旗下所以Email。
public class Solution {
/**
* @param accounts: List[List[str]]
* @return: return a List[List[str]]
*/
int[] father;
public List<List<String>> accountsMerge(List<List<String>> accounts) {
father = new int[accounts.size()];
for (int i = 0; i < accounts.size(); i++) {
father[i] = i;
}
//union
Map<String, List<Integer>> emailToIds = getEmailToIds(accounts);
for (List<Integer> ids: emailToIds.values()) {
for (int i = 1; i < ids.size(); i++) {
union(ids.get(i), ids.get(0));
}
}
//merge
Map<Integer, Set<String>> idToEmailSet = getIdToEmailSet(accounts);
List<List<String>> mergedAccounts = new ArrayList<>();
for (Map.Entry<Integer, Set<String>> entry : idToEmailSet.entrySet()) {
Integer userId = entry.getKey();
List<String> emails = new ArrayList(entry.getValue());
Collections.sort(emails);
emails.add(0, accounts.get(userId).get(0));
mergedAccounts.add(emails);
}
return mergedAccounts;
}
private Map<String, List<Integer>> getEmailToIds(List<List<String>> accounts) {
Map<String, List<Integer>> emailToIds = new HashMap<>();
for (int userId = 0; userId < accounts.size(); userId++) {
List<String> account = accounts.get(userId);
for (int i = 1; i < account.size(); i++) {
List<Integer> ids = emailToIds.getOrDefault(account.get(i), new ArrayList<Integer>());
ids.add(userId);
emailToIds.put(account.get(i), ids);
}
}
return emailToIds;
}
private Map<Integer, Set<String>> getIdToEmailSet(List<List<String>> accounts) {
Map<Integer, Set<String>> idToEmailSet = new HashMap<>();
for (int userId = 0; userId < accounts.size(); userId++) {
List<String> account = accounts.get(userId);
int root = find(userId);
Set<String> emails = idToEmailSet.getOrDefault(root, new HashSet<String>());
for (int i = 1; i < account.size(); i++) {
emails.add(account.get(i));
}
idToEmailSet.put(root, emails);
}
return idToEmailSet;
}
private void union (int id1, int id2) {
int root1 = find(id1);
int root2 = find(id2);
if (root1 != root2) {
father[root1] = root2;
}
}
private int find(int id) {
int node = id;
while (father[node] != node) {
node = father[node];
}
int root = node;
while (id != root) {
int tmp = father[id];
father[id] = root;
id = tmp;
}
return root;
}
}
Accounts Merge的更多相关文章
- 【LeetCode】721. Accounts Merge 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/accounts ...
- [LeetCode] Accounts Merge 账户合并
Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...
- [Swift]LeetCode721. 账户合并 | Accounts Merge
Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...
- [leetcode]721. Accounts Merge账户合并
Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...
- 721. Accounts Merge合并电子邮件账户
[抄题]: Given a list accounts, each element accounts[i] is a list of strings, where the first element ...
- [LeetCode] 721. Accounts Merge 账户合并
Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...
- LeetCode 721. Accounts Merge
原题链接在这里:https://leetcode.com/problems/accounts-merge/ 题目: Given a list accounts, each element accoun ...
- 【leetcode】721. Accounts Merge(账户合并)
Given a list of accounts where each element accounts[i] is a list of strings, where the first elemen ...
- 721. Accounts Merge
https://leetcode.com/problems/accounts-merge/description/ class UnionFound { public: unordered_map&l ...
随机推荐
- 017 Android 获取手机SIM卡序列号和读取联系人
1.获取手机SIM卡序列号 //5.存储sim卡系列号 //5.1获取sim卡系列号 TelephonyManager manager = (TelephonyManager) getSystemSe ...
- c#序列化基类(包含派生类继承DynamicObject和 IXmlSerializable)对象
直接上代码 using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.Schema; using ...
- Python——成员变量
一.类变量 在类命名空间内定义的变量就属于类变量,python允许使用类来修改.读取类变量. 例: class a: b = '我是类变量' def c(self): print (a.b) # 通过 ...
- CH02基于ZYNQ的嵌入式LINUX移植
CH02基于ZYNQ的嵌入式LINUX移植 1.1概述 实验环境: Windows 10 专业版 Vmware workstation 14.1.1 Ubuntu 16.04.3 Xilinx SDx ...
- linux命令行删除N天前的数据的命令
命令: find . -mtime +N -type f -name "*.log.*" -exec rm -f {} \; 简单解释: find .查询 ; -mtime 规 ...
- Nokia5130不能上网
说明 我是一个挺怀旧的人,一直想入手一个好几年前买的Nokia5130. 于是昨天在淘宝上买了一个,花了我一百多.不过早就停产了,买到的自然是翻新机. 收到货的时候,看似一切美好,但是下载了个uc的j ...
- 音视频入门-08-RGB&YUV
* 音视频入门文章目录 * YUV & RGB 相互转换公式 YCbCr 的 Y 与 YUV 中的 Y 含义一致,Cb 和 Cr 与 UV 同样都指色彩,Cb 指蓝色色度,Cr 指红色色度,在 ...
- DevExtreme学习笔记(一) DataGrid中js分析
1.overviewjs采用 $(function() { $("#gridContainer").dxDataGrid({ dataSource: { store: { type ...
- raspbian buster阿里镜像
配置以前,谨记教诲,先去看一下是否有对应版本的源,如下所示,阿里这更新速度...确实挺赶潮流的 最后就是正常更新即可,这样就快多了,要不然用国外的源,还不知道要等到猴年马月的. sudo apt-ge ...
- javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificatio
场景:Java调用PHP接口,代码部署在服务器上后,调用报错,显示PHP服务器那边证书我这边服务器不信任(我猜的). 异常信息: 2019-08-06 14:00:09,102 [http-nio-4 ...