mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
100 lines
4.0 KiB
Python
100 lines
4.0 KiB
Python
#coding: utf-8
|
||
''' mbinary
|
||
#######################################################################
|
||
# File : accountsMerge.py
|
||
# Author: mbinary
|
||
# Mail: zhuheqin1@gmail.com
|
||
# Blog: https://mbinary.xyz
|
||
# Github: https://github.com/mbinary
|
||
# Created Time: 2018-12-18 17:07
|
||
# Description:
|
||
给定一个列表 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 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。
|
||
#######################################################################
|
||
'''
|
||
|
||
class Solution(object):
|
||
def accountsMerge(self, accounts):
|
||
"""
|
||
:type accounts: List[List[str]]
|
||
:rtype: List[List[str]]
|
||
"""
|
||
mailDic = {}
|
||
for ct,i in enumerate(accounts):
|
||
for j in i[1:]:
|
||
mailDic[j] = (ct,i[0])
|
||
mails = {mail:idx for idx,mail in enumerate(mailDic.keys())}
|
||
mailNum = len(mails)
|
||
self.findSet = [i for i in range(mailNum)]
|
||
for li in accounts:
|
||
n = len(li)
|
||
for i in range(1,n-1):
|
||
for j in range(i+1,n):
|
||
self.union(mails[li[i]],mails[li[j]])
|
||
dic = {}
|
||
mails = {j:i for i,j in mails.items()}
|
||
for i in range(mailNum):
|
||
mail = mails[i]
|
||
n = mailDic[mails[self.find(i)]][0]
|
||
if n in dic:
|
||
dic[n].append(mail)
|
||
else:
|
||
dic[n] = [mail]
|
||
nameId = {i[0]:i[1] for i in mailDic.values()}
|
||
return [[nameId[i]]+sorted(mail) for i,mail in dic.items()]
|
||
def find(self,i):
|
||
if self.findSet[i]!=i:
|
||
n = self.find(self.findSet[i])
|
||
self.findSet[i] = n
|
||
return self.findSet[i]
|
||
def union(self,i,j):
|
||
if i!=j:
|
||
n = self.find(i)
|
||
if n!=self.find(j):
|
||
self.findSet[n] = self.findSet[j]
|
||
|
||
class Solution2:
|
||
'''并查映射'''
|
||
def accountsMerge(self, accounts):
|
||
"""
|
||
:type accounts: List[List[str]]
|
||
:rtype: List[List[str]]
|
||
"""
|
||
mailDic = {j:ct for ct,i in enumerate(accounts) for j in i[1:]}
|
||
self.findSet = {i:i for i in mailDic}
|
||
for li in accounts:
|
||
n = len(li)
|
||
for i in range(1,n-1):
|
||
for j in range(i+1,n):
|
||
self.union(li[i],li[j])
|
||
dic = {}
|
||
for mail in self.findSet:
|
||
n = mailDic[self.find(mail)]
|
||
if n in dic:
|
||
dic[n].append(mail)
|
||
else:
|
||
dic[n] = [mail]
|
||
return [[accounts[i][0]]+sorted(mail) for i,mail in dic.items()]
|
||
def find(self,i):
|
||
if self.findSet[i]!=i:
|
||
n = self.find(self.findSet[i])
|
||
self.findSet[i] = n
|
||
return self.findSet[i]
|
||
def union(self,i,j):
|
||
if i!=j:
|
||
n = self.find(i)
|
||
if n!=self.find(j):
|
||
self.findSet[n] = self.findSet[j]
|