zoukankan      html  css  js  c++  java
  • 721. Accounts Merge合并电子邮件账户

    [抄题]:

    Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements are emails representing emails of the account.

    Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name.

    After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order.

    Example 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: 
    The first and third John's are the same person as they have the common email "johnsmith@mail.com".
    The second John and Mary are different people as none of their email addresses are used by other accounts.
    We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'], 
    ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    [思维问题]:

    不知道怎么用hashmap来做union find:

    多用几个hashmap,用一个parents来存第一个邮箱,用一个owner来存用户,用一个union来存关系 

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    [一句话思路]:

    为了排序,把每组的第一个邮箱都当作该组的parent

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. 忘记写find函数了:union find题目必须写的吧
    2. 第一位邮件的parent就是自身,所以从第二位开始处理parent
    3. 往map的tree里加东西包括:得到树+往树里加东西两步 不涉及什么图不图的
    unions.get(p).add(a.get(i))

    [二刷]:

    [三刷]:

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    union find中为了排序必须要有parent的哈希表

    [复杂度]:Time complexity: O(n) Space complexity: O(n)

    [算法思想:迭代/递归/分治/贪心]:

    [关键模板化代码]:

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

    684. Redundant Connection 去掉一条边后变成树

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

    class Solution {
        public List<List<String>> accountsMerge(List<List<String>> accounts) {
            //cc
            List<List<String>> results = new ArrayList<List<String>>();
            if (accounts == null || accounts.size() == 0) return results;
            
            //ini: 3 hashmap, put into parents owner
            HashMap<String, String> parents = new HashMap<>();
            HashMap<String, String> owners = new HashMap<>();
            HashMap<String, TreeSet<String>> unions = new HashMap<>();
            for (List<String> a : accounts) {
                for (int i = 1; i < a.size(); i++) {
                    parents.put(a.get(i), a.get(i));
                    owners.put(a.get(i), a.get(0));
                }
            }
            
            //renew parents
            for (List<String> a : accounts) {
                String p = find(a.get(1), parents);
                for (int i = 2; i < a.size(); i++) {
                    parents.put(find(a.get(i), parents), p);
                }
            }
            
            //put into unions to order
            for (List<String> a : accounts) {
                String p = find(a.get(1), parents);
                if (!unions.containsKey(p)) unions.put(p, new TreeSet());
                for (int i = 1; i < a.size(); i++) {
                    unions.get(p).add(a.get(i));
                }
            }
            
            //add to res
            for (String a : unions.keySet()) {
                List<String> result = new ArrayList<String>(unions.get(a));
                result.add(0, owners.get(a));
                results.add(result);
            }
            
            //return
            return results;
        }
        
        public String find(String s, HashMap<String, String> map) {
            return map.get(s) == s ? s : find(map.get(s), map);
        }
    }
    View Code
  • 相关阅读:
    python2将str类型与unicode类型字符串写入文件的编码问题
    正则表达式匹配邮箱
    python读取excel表格
    python正则匹配re.search与re.findall的区别
    python使用join提取列表类型中的数字字符串
    判断一个python字符串中是否包含中文字符
    wordstation中虚拟机关机hang住,无法正常关机
    网络中涉及到优先级的主设备会被抢占与非抢占。
    [转]一天一点学习Linux之Inode详解
    [转]理解Linux文件系统之inode(非ext格式)
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9140114.html
Copyright © 2011-2022 走看看