【1月打卡~Leetcode每日一题】721. 账户合并(难度:中等)

721. 账户合并

给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该账户的邮箱地址。
现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。请注意,即使两个账户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的账户,但其所有账户都具有相同的名称。
合并账户后,按以下格式返回账户:每个账户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。账户本身可以以任意顺序返回。

并查集+哈希表

注意看一下数据

  • accounts的长度将在[1,1000]的范围内。

说明n²复杂度的代码基本可以过

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        n = len(accounts)
        parent = list(range(n))

        def find(index):
            if index != parent[index]:
                parent[index] = find(parent[index])
            return parent[index]

        def union(index1,index2):
            parent[find(index2)] = find(index1)


        for i in range(n):
            accounts[i] = [accounts[i][0]] + list(set(accounts[i][1:]))
            
        visited = set()
        dic = collections.defaultdict(set)
        for i in range(n-1):
            for j in range(i+1,n):
                leni,lenj = len(accounts[i]),len(accounts[j])
                lensum = len(set(accounts[i][1:]+accounts[j][1:]))
                if lensum^(leni+lenj-2):
                    union(i,j)
        
        for i in range(n):
            if i not in visited:
                dic[i] = set(accounts[i][1:])
            for j in range(i+1,n):
                if j not in visited and find(i)==find(j):
                    visited.add(j)
                    dic[i] |= set(accounts[j][1:])

        ans =[]
        for key,value in dic.items():
            stand = [accounts[key][0]] + sorted(list(value))
            ans.append(stand)
        return ans

时间复杂度O(n²)

优化:

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))

    def union(self, index1: int, index2: int):
        self.parent[self.find(index2)] = self.find(index1)

    def find(self, index: int) -> int:
        if self.parent[index] != index:
            self.parent[index] = self.find(self.parent[index])
        return self.parent[index]

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        emailToIndex = dict()
        emailToName = dict()

        for account in accounts:
            name = account[0]
            for email in account[1:]:
                if email not in emailToIndex:
                    emailToIndex[email] = len(emailToIndex)
                    emailToName[email] = name
        
        uf = UnionFind(len(emailToIndex))
        for account in accounts:
            firstIndex = emailToIndex[account[1]]
            for email in account[2:]:
                uf.union(firstIndex, emailToIndex[email])
        
        indexToEmails = collections.defaultdict(list)
        for email, index in emailToIndex.items():
            index = uf.find(index)
            indexToEmails[index].append(email)
        
        ans = list()
        for emails in indexToEmails.values():
            ans.append([emailToName[emails[0]]] + sorted(emails))
        return ans

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值