diff --git a/src/main/java/com/thealgorithms/graph/AccountMerge.java b/src/main/java/com/thealgorithms/graph/AccountMerge.java new file mode 100644 index 000000000000..cf934a72eb68 --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/AccountMerge.java @@ -0,0 +1,112 @@ +package com.thealgorithms.graph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Merges account records using Disjoint Set Union (Union-Find) on shared emails. + * + *
Input format: each account is a list where the first element is the user name and the
+ * remaining elements are emails.
+ */
+public final class AccountMerge {
+ private AccountMerge() {
+ }
+
+ public static List> mergeAccounts(List
> accounts) {
+ if (accounts == null || accounts.isEmpty()) {
+ return List.of();
+ }
+
+ UnionFind dsu = new UnionFind(accounts.size());
+ Map
> merged = new ArrayList<>();
+ for (Map.Entry
> accounts = List.of(List.of("abc", "abc@mail.com", "abx@mail.com"), List.of("abc", "abc@mail.com", "aby@mail.com"), List.of("Mary", "mary@mail.com"), List.of("John", "johnnybravo@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+
+ List
> expected = List.of(List.of("John", "johnnybravo@mail.com"), List.of("Mary", "mary@mail.com"), List.of("abc", "abc@mail.com", "abx@mail.com", "aby@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testAccountsWithSameNameButNoSharedEmailStaySeparate() {
+ List
> accounts = List.of(List.of("Alex", "alex1@mail.com"), List.of("Alex", "alex2@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+ List
> expected = List.of(List.of("Alex", "alex1@mail.com"), List.of("Alex", "alex2@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testEmptyInput() {
+ assertEquals(List.of(), AccountMerge.mergeAccounts(List.of()));
+ }
+
+ @Test
+ void testNullInput() {
+ assertEquals(List.of(), AccountMerge.mergeAccounts(null));
+ }
+
+ @Test
+ void testTransitiveMergeAndDuplicateEmails() {
+ List
> accounts = List.of(List.of("A", "a1@mail.com", "a2@mail.com"), List.of("A", "a2@mail.com", "a3@mail.com"), List.of("A", "a3@mail.com", "a4@mail.com", "a4@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+
+ List
> expected = List.of(List.of("A", "a1@mail.com", "a2@mail.com", "a3@mail.com", "a4@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testAccountsWithNoEmailsArePreserved() {
+ List
> accounts = List.of(List.of("Alex"), List.of("Alex", "alex1@mail.com"), List.of("Bob"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+ List
> expected = List.of(List.of("Alex"), List.of("Alex", "alex1@mail.com"), List.of("Bob"));
+
+ assertEquals(expected, merged);
+ }
+}