zoukankan      html  css  js  c++  java
  • Leetcode 721 账户合并

    题目定义:

    给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),
    其余元素是 emails 表示该账户的邮箱地址。
    
    现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。
    请注意,即使两个账户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。
    一个人最初可以拥有任意数量的账户,但其所有账户都具有相同的名称。
    
    合并账户后,按以下格式返回账户:每个账户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。
    账户本身可以以任意顺序返回。
    
     
    
    示例 1:
    
        输入:
        accounts = [["John", "johnsmith@mail.com", "john00@mail.com"],
     ["John", "johnnybravo@mail.com"],
     ["John", "johnsmith@mail.com", "john_newyork@mail.com"],
     ["Mary", "mary@mail.com"]]
        输出:
        [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],  
    ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
        解释:
        第一个和第三个 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']] 也是正确的。
    

    方式一(并查集):

    class Solution {
        private Map<String,Integer> emailToIndex = new HashMap<>();
        private Map<String,String> emailToName = new HashMap<>();
        public List<List<String>> accountsMerge(List<List<String>> accounts) {
            int emailCount = getEdges(accounts);
            UnionFind unionFind = getUnionFind(emailCount,accounts);
            Map<Integer,List<String>> indexToEmails = getIndexToEmails(unionFind);
            return getMerged(indexToEmails);
    
        }
    
        private List<List<String>> getMerged(Map<Integer,List<String>> indexToEmails){
            List<List<String>> merged = new ArrayList<>();
            for(List<String> emails : indexToEmails.values()){
                Collections.sort(emails);
                String name = emailToName.get(emails.get(0));
                List<String> account = new ArrayList<>();
                account.add(name);
                account.addAll(emails);
                merged.add(account);
            }
            return merged;
        }
    
        //根据并查集将相同的邮箱放在一起
        private Map<Integer,List<String>> getIndexToEmails(UnionFind unionFind){
            Map<Integer,List<String>> map = new HashMap<>();
            for(String email : emailToIndex.keySet()){
                int index = unionFind.find(emailToIndex.get(email));
                List<String> account = map.getOrDefault(index,new ArrayList<>());
                account.add(email);
                map.put(index,account);
            }
            return map;
        }
    
        //生成并查集
        private UnionFind getUnionFind(int emailCount,List<List<String>> accounts){
            UnionFind unionFind = new UnionFind(emailCount);
            for(List<String> account : accounts){
                int firstIndex = emailToIndex.get(account.get(1));
                for(int i = 2; i < account.size();i++){
                    int nextIndex = emailToIndex.get(account.get(i));
                    unionFind.union(nextIndex,firstIndex);
                }
            }
            return unionFind;
        }
    
        //统计所有的邮箱信息,按照 email-name email-count 生成两个map
        private int getEdges(List<List<String>> accounts){
            int emailCount = 0;
            for(List<String> account : accounts){
                String name = account.get(0);
                for(int i = 1; i < account.size(); i++){
                    if(!emailToIndex.containsKey(account.get(i))){
                        emailToIndex.put(account.get(i),emailCount++);
                        emailToName.put(account.get(i),name);
                    }
                }
            }
            return emailCount;
        }
    }
    class UnionFind{
        int[] parent;
    
        public UnionFind(int n){
            parent = new int[n];
            for(int i = 0; i < n; i++)
                parent[i] = i;
        }
    
        public int find(int index){
            if(parent[index] != index)
                parent[index] = find(parent[index]);
            return parent[index];
        }
    
        public void union(int index1,int index2){
            parent[find(index1)] = find(index2);
        }
    }
    

    参考:

    https://leetcode-cn.com/problems/accounts-merge/solution/zhang-hu-he-bing-by-leetcode-solution-3dyq/

  • 相关阅读:
    一个大浪Java罢工(一个)安装JDK和环境变量配置
    awk的实施例
    【phpMyAdmin】更改配置文件连接到其他server
    Humming Bird A20 SPI2驱动编译
    2014Esri国际用户大会ArcGIS Online
    POJ 2724 Purifying Machine(最大独立集)
    python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹
    《java系统性能优化》--2.高速缓存
    XAMPP on Mac 组态 Virual Host
    Explicit keyword
  • 原文地址:https://www.cnblogs.com/CodingXu-jie/p/14291998.html
Copyright © 2011-2022 走看看