721. Accounts Merge

题目在这里插入图片描述

就是说给出一系列人物的名字和邮箱,里面的人可能重名,但要将列表合并,将同人物的邮箱合并起来。

思路及代码

第一步,我们先假定有以下的列表:

[
["John", "johnsmith@mail.com", "john00@mail.com"], # Account 0
["John", "johnnybravo@mail.com"], # Account 1
["John", "johnsmith@mail.com", "john_newyork@mail.com"],  # Account 2
["Mary", "mary@mail.com"] # Account 3
]

接下来,构建一个将电子邮件映射到帐户列表的emails_accounts_map,该列表可用于跟踪链接到哪个帐户的电子邮件。这就是我们的图像。

得到一个映射,关于邮箱对应的账户,就需要合并。

# emails_accounts_map of email to account ID
{
  "johnsmith@mail.com": [0, 2],
  "john00@mail.com": [0],
  "johnnybravo@mail.com": [1],
  "john_newyork@mail.com": [2],
  "mary@mail.com": [3]
}

python DFS遍历:

class Solution(object):
    def accountsMerge(self, accounts):
        from collections import defaultdict
        visited_accounts = [False] * len(accounts)
        emails_accounts_map = defaultdict(list)
        res = []
        # Build up the graph.
        for i, account in enumerate(accounts):
            for j in range(1, len(account)):
                email = account[j]
                emails_accounts_map[email].append(i)
        # DFS code for traversing accounts.
        def dfs(i, emails):
            if visited_accounts[i]:
                return
            visited_accounts[i] = True
            for j in range(1, len(accounts[i])):
                email = accounts[i][j]
                emails.add(email)
                for neighbor in emails_accounts_map[email]:
                    dfs(neighbor, emails)
        # Perform DFS for accounts and add to results.
        # 查找所有的账户,使用深度优先算法,遍历所有的账户,每个账户只查找一遍,然后即可实现合并。
        for i, account in enumerate(accounts):
            if visited_accounts[i]:
                continue
            name, emails = account[0], set()
            dfs(i, emails)
            res.append([name] + sorted(emails))
        return res

高效代码

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        
        N = len(accounts)
        acc_graph = [set() for _ in range(N)]
        
        emails_map = {}
        for i, (name, *emails) in enumerate(accounts):
            uniques = []
            for email in emails:
                if email in emails_map:
                    j = emails_map[email]
                    acc_graph[i].add(j)
                    acc_graph[j].add(i)
                else:
                    emails_map[email] = i
                    uniques.append(email)
            accounts[i] = name, uniques
        
        visited = [False]*N
        out = []
        
        for i in range(N):
            if visited[i]:
                continue
            visited[i], stack = True, [i]
            account = [] 
            while stack:
                i = stack.pop()
                account.extend(accounts[i][1])
                for ch in acc_graph[i]:
                    if not visited[ch]:
                        visited[ch] = True
                        stack.append(ch)
            account.sort(reverse=True)
            account.append(accounts[i][0])
            account.reverse()
            out.append(account)
            
        return out
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值