Accounts Merge

 

  1. Clarify the problem:

    • The problem requires us to merge accounts with the same email addresses and return a list of merged accounts.
    • Each account is represented by a list of strings, where the first element is the name of the account owner, and the following elements are email addresses associated with that account.
    • We need to group accounts with the same email addresses and merge them into a single account while preserving the original order of the accounts.
  2. Analyze the problem:

    • Input: A list of lists representing accounts, where each account contains a name and email addresses.
    • Output: A list of lists representing merged accounts.
    • Constraints:
      • The length of the accounts list is between 1 and 10^4.
      • The length of each account is between 1 and 10.
      • The email addresses are lowercase alphanumeric characters.
      • The number of email addresses can be different for each account.
  3. Design an algorithm:

    • We can solve this problem using the Union-Find algorithm.
    • We need to build a graph where each email address is a node, and an edge exists between two nodes if they belong to the same account.
    • We iterate through the accounts and add each email address to the graph, creating an edge between the email addresses of the same account.
    • After constructing the graph, we perform a depth-first search (DFS) starting from each email address to find all connected email addresses.
    • We group the connected email addresses and add them to the result list as merged accounts.
    • To optimize the process, we can use a hashmap to map each email address to its corresponding account owner.
    • Finally, we return the list of merged accounts.
  4. Explain your approach:

    • We will implement the Union-Find algorithm to merge accounts with the same email addresses.
    • We create a hashmap to map each email address to its corresponding account owner.
    • We create a graph using a dictionary, where each email address is a key, and its value is a set of connected email addresses.
    • We iterate through the accounts and add each email address to the graph, creating an edge between the email addresses of the same account.
    • After constructing the graph, we perform a depth-first search (DFS) starting from each email address to find all connected email addresses.
    • We group the connected email addresses and add them to the result list as merged accounts, appending the account owner's name at the beginning.
    • Finally, we return the list of merged accounts.
  5. Write clean and readable code:

    python
  6. def accountsMerge(accounts): def find(parent, i): if parent[i] != i: parent[i] = find(parent, parent[i]) return parent[i] def union(parent, rank, i, j): root_i = find(parent, i) root_j = find(parent, j) if rank[root_i] < rank[root_j]: parent[root_i] = root_j elif rank[root_i] > rank[root_j]: parent[root_j] = root_i else: parent[root_j] = root_i rank[root_i] += 1 email_to_name = {} email_to_id = {} id_counter = 0 for account in accounts: name = account[0] emails = account[1:] for email in emails: if email not in email_to_id: email_to_id[email] = id_counter id_counter += 1 email_to_name[email] = name parent = [i for i in range(id_counter)] rank = [0] * id_counter for account in accounts: emails = account[1:] root = find(parent, email_to_id[emails[0]]) for email in emails[1:]: union(parent, rank, root, email_to_id[email]) merged_accounts = {} for email, id in email_to_id.items(): root = find(parent, id) if root in merged_accounts: merged_accounts[root].append(email) else: merged_accounts[root] = [email] merged_results = [] for emails in merged_accounts.values(): name = email_to_name[emails[0]] merged_results.append([name] + sorted(emails)) return merged_results
  7. Test your code:

    python
  8. # Example 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"] ] print(accountsMerge(accounts)) # Output: [ # ["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"], # ["John","johnnybravo@mail.com"], # ["Mary","mary@mail.com"] # ] # Example 2 accounts = [ ["Gabe", "gabe@mail.com", "gabriel@mail.com"], ["Gabe", "gabriel@mail.com", "gabriel1@mail.com"], ["Gabe", "gabriel1@mail.com", "gabriel2@mail.com"] ] print(accountsMerge(accounts)) # Output: [["Gabe","gabriel1@mail.com","gabriel2@mail.com","gabriel@mail.com","gabe@mail.com"]] # Additional Test Case accounts = [ ["Alice", "alice@mail.com"], ["Bob", "bob@mail.com"], ["Charlie", "charlie@mail.com"], ] print(accountsMerge(accounts)) # Output: [["Alice","alice@mail.com"],["Bob","bob@mail.com"],["Charlie","charlie@mail.com"]]
  9. Optimize if necessary:

    • The solution has a time complexity of O(n * log(m)), where n is the number of accounts and m is the total number of email addresses.
    • The time complexity is dominated by the Union-Find operations, which have a logarithmic time complexity.
    • The space complexity is O(n * m) due to the hashmap and graph representation.
  10. Handle error cases:

    • There are no specific error cases to handle for this problem.
    • The problem guarantees that the accounts list will have at least one account, and each account will have at least one email address.
  11. Discuss complexity analysis:

    • The time complexity of the solution is O(n * log(m)), where n is the number of accounts and m is the total number of email addresses.
    • The space complexity is O(n * m) due to the hashmap and graph representation.
    • The solution is efficient for the given constraints and provides the correct output.
Next Post Previous Post