给定一个列表 accounts
,每个元素 accounts[i]
是一个字符串列表,其中第一个元素 accounts[i][0]
是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。
现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。
合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
例子 1:
Input: accounts = [["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: 第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"。 第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。 我们可以以任何顺序返回这些列表,例如答案[['Mary','mary@mail.com'],['John','johnnybravo@mail.com'], ['John','john00@mail.com','john_newyork@mail.com','johnsmith@mail.com']]仍然会被接受。
注意:
accounts
的长度将在[1,1000]
的范围内。accounts[i]
的长度将在[1,10]
的范围内。accounts[i][j]
的长度将在[1,30]
的范围内。
Review:
看到动态联通问题就要考虑是否应该用并查集算法解决,这个题我的思维很混乱,使用了大量字典,算法可能有漏洞,但是我也很佩服我自己在这么乱的思维下还可以一次ac且速度不慢
使用了TreeSet进行排序,不知道还有什么好方法
Code:
class Solution {
public List<List<String>> accountsMerge(List<List<String>> accounts) {
final int len=accounts.size();
int[] relation=new int[len];
Map<String,Integer> dict = new HashMap<>();
for (int i = 0; i < len; i++) {
relation[i] = i;
List<String> list = accounts.get(i);
for (int j = 1; j < list.size(); j++) {
Integer integer = dict.putIfAbsent(list.get(j), i);
if (integer!=null){
union(relation,i,integer);
}
}
}
List<Set<String>> res = new ArrayList<>();
int[] bos = new int[len];
//遍历排序
for (int i = 0; i < len; i++) {
int find = find(relation, i);
if (bos[find]==0){
res.add(new TreeSet<>(accounts.get(i)));
bos[find] = res.size();
}else {
Set<String> set = res.get(bos[find] - 1);
set.addAll(accounts.get(i));
}
}
//排序
int i = 0;
List<List<String>> result = new ArrayList<>();
for (Set<String> re:res) {
result.add(i++,new ArrayList<>(re));
}
return result;
}
private void union(int[] relation,int x ,int y){
x = find(relation,x);
y = find(relation,y);
if (x!=y){
relation[y] = x;
}
}
private int find(int[] relation,int index){
while (relation[index]!=index){
index = relation[index];
}
return index;
}
}