721. 账户合并

117 阅读1分钟

721. 账户合并

方法一:暴力

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        if not accounts:
            return
        lookup = defaultdict(list)
        res = []
        for account in accounts:
            name = account[0]
            email = set(account[1:])
            lookup[name].append(email)
            for e in lookup[name][:-1]:
                if e & email:
                    lookup[name].remove(e)
                    lookup[name][-1].update(e)
        for key, val in lookup.items():
            for tmp in val:
                res.append([key] + list(sorted(tmp)))
        return res

方法二:dfs

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        graph = defaultdict(set)
        email_to_name = defaultdict()
        for account in accounts:
            name, emails = account[0], account[1:]
            for email in emails:
                email_to_name[email] = name
                graph[emails[0]].add(email)
                graph[email].add(emails[0])
        visited = set()
        res = []

        def dfs(e):
            new_list.append(e)
            for t in graph[e]:
                if t not in visited:
                    visited.add(t)
                    dfs(t)
            
        for e in graph:
            if e not in visited:
                visited.add(e)
                new_list = []
                dfs(e)
                res.append([email_to_name[e]] + sorted(new_list))
        return res

方法三:bfs

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        graph = defaultdict(set)
        email_to_name = defaultdict()
        for account in accounts:
            name, emails = account[0], account[1:]
            for email in emails:
                email_to_name[email] = name
                graph[emails[0]].add(email)
                graph[email].add(emails[0])
        visited = set()
        res = []

        def bfs(e):
            ans = []
            stack = deque()
            stack.appendleft(e)
            while stack:
                tmp = stack.pop()
                ans.append(tmp)
                for t in graph[tmp]:
                    if t not in visited:
                        visited.add(t)
                        stack.appendleft(t)
            return ans
            
        for e in graph:
            if e not in visited:
                visited.add(e)
                ans = bfs(e)
                res.append([email_to_name[e]] + sorted(ans))
        return res

方法四:并查集

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        f = {}
        
        def find(x):
            f.setdefault(x, x)
            while f[x] != x:
                f[x] = f[f[x]]
                x = f[x]
            return x

        def union(x, y):
            f[find(x)] = find(y)

        lookup = {}
        n = len(accounts)
        for idx, account in enumerate(accounts):
            name, email = account[0], account[1:]
            for e in email:
                if e in lookup:
                    union(idx, lookup[e])
                else:
                    lookup[e] = idx

        disJoinSet = defaultdict(set)
        for i in range(n):
            tmp = find(i)
            for es in accounts[i][1:]:
                disJoinSet[tmp].add(es)
            
        res = []
        for key, val in disJoinSet.items():
            res.append([accounts[key][0]] + list(sorted(val)))
        return res