ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

力扣:账户合并

2020-12-07 21:32:17  阅读:356  来源: 互联网

标签:parent 账户 int father 合并 力扣 accounts mail com


题目描述


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

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:
第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 “johnsmith@mail.com”。
第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。

题目分析


题目要求很明确,通过具有相同的邮件,确认两个相同姓名的用户是否是同一个用户,是则返回该用户的所有邮箱的合集。

1、构建Map ,保存邮箱到姓名的关系,但因为姓名是存在重复的,所以不能以姓名作为并查集的根,这里想到了采用 accounts 的下标。

Map<String , Integer> parent = new HashMap<>();

2、此外,还需要构建一个中间结果Map , 保存下标和邮箱的映射,此时的邮箱是去重后的(该下标代表的用户,所拥有的的所有邮箱),采用 TreeSet 进行去重处理。

Map<Integer, TreeSet<String>> temp = new HashMap<>();

3、从中间结果 temp 中还原出 List<List> ,通过下标获取 accounts 的姓名,并将姓名和邮箱添加到同一个 List 得到一个用户和所有的邮箱。

int root = entry.getKey();
String name = accounts.get(root).get(0);
list.add(name);
list.addAll(entry.getValue());

AC代码:

class Solution {
	
	// 查找根
    public int find(int[] father , int x){
        return father[x] == -1 ? x : find(father , father[x]);
    }
	
	// 合并并查集
    public void union(int[] father , int x , int y){
        int x_parent = find(father , x);
        int y_parent = find(father , y);
        if(x_parent != y_parent){
            father[y_parent] = x_parent;
        }
    }

    public List<List<String>> accountsMerge(List<List<String>> accounts) {
        Map<String , Integer> parent = new HashMap<>();
        int[] father = new int[accounts.size()];
        Arrays.fill(father , -1);
        // 构建 姓名和邮箱 之间的并查集
        for(int i = 0 ; i < accounts.size(); i ++){
            List<String> account = accounts.get(i);
            for(int j = 1 ; j < account.size() ; j ++){
                String email = account.get(j);
                // 如果邮箱已经存在,说明存在集合是属于同一个用户的,将其合并
                if(parent.containsKey(email)){
                    union(father , parent.get(email) , i);
                }
                // 如果不存在,加入
                parent.put(email , i);
            }
        }
        
        // 将并查集根相同,邮箱合并到一起,得到中间结果 temp 
        Map<Integer , Set<String>> temp = new HashMap<>();
        for(int i = 0 ; i < accounts.size() ; i ++){
            int root = find(father , i);
            List<String> account = accounts.get(i);
            List<String> emails = account.subList(1 , account.size());
            // 如果 根 已经出现过,现在只需要将邮箱合并,因为是 Set 无需考虑是否会重复
            if(temp.containsKey(root)){
                temp.get(root).addAll(emails);
            } else {
            // 如果没有出现 此根 ,构建一个 Set 集合,将邮箱加入
                temp.put(root , new TreeSet<>(emails));
            }
        }

        // 将中间结果 temp 转换为输出的返回类型
        List<List<String>> result = new ArrayList<>();
        for(Map.Entry<Integer , Set<String>> entry : temp.entrySet()){
            List<String> list = new ArrayList<>();
            int root = entry.getKey();
            String name = accounts.get(root).get(0); // 通过下标获取姓名
            list.add(name); // 将姓名添加到 list
            list.addAll(entry.getValue()); // 然后将邮箱添加到 list 
            result.add(list);
        }
        return result;
    }
}

标签:parent,账户,int,father,合并,力扣,accounts,mail,com
来源: https://blog.csdn.net/weixin_42479017/article/details/110836561

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有