From f96675dd232720ad60a382404d23af28594e36df Mon Sep 17 00:00:00 2001 From: CodersAcademy006 <104912634+CodersAcademy006@users.noreply.github.com> Date: Thu, 22 Aug 2024 23:55:43 -0700 Subject: [PATCH] feat: Add Solution.java --- .../Solution.java | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/Solution.java diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/Solution.java b/solution/1900-1999/1948.Delete Duplicate Folders in System/Solution.java new file mode 100644 index 0000000000000..26b73b90592c0 --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/Solution.java @@ -0,0 +1,117 @@ +import java.util.*; + +class TrieNode { + Map children; + Integer id; + + public TrieNode() { + this.children = new HashMap<>(); + this.id = null; + } +} + +public class Solution { + public List> deleteDuplicateFolder(List> paths) { + TrieNode root = new TrieNode(); + + // Step 1: Build Trie (Tree) + for (List path : paths) { + TrieNode node = root; + for (String folder : path) { + node = node.children.computeIfAbsent(folder, k -> new TrieNode()); + } + } + + // Step 2: Assign unique IDs to subtrees + Map> subtreeMap = new HashMap<>(); + + getSubtreeId(root, subtreeMap); + + // Step 3: Mark duplicates + Set duplicates = new HashSet<>(); + for (List nodes : subtreeMap.values()) { + if (nodes.size() > 1) { // If more than one node has the same structure, mark as duplicate + duplicates.addAll(nodes); + } + } + + // Step 4: Collect remaining paths + List> ans = new ArrayList<>(); + collectRemainingPaths(root, new ArrayList<>(), duplicates, ans); + + return ans; + } + + private String getSubtreeId(TrieNode node, Map> subtreeMap) { + if (node.children.isEmpty()) { + return ""; // Empty subtree has no ID + } + + // Sort children lexicographically and form a string representing the subtree + List subtreeList = new ArrayList<>(); + for (Map.Entry entry : node.children.entrySet()) { + String folder = entry.getKey(); + TrieNode child = entry.getValue(); + subtreeList.add(folder + "(" + getSubtreeId(child, subtreeMap) + ")"); + } + Collections.sort(subtreeList); + + // Create a unique string representation of the subtree + String subtree = String.join(",", subtreeList); + + // Map the subtree representation to the node + subtreeMap.computeIfAbsent(subtree, k -> new ArrayList<>()).add(node); + + return subtree; + } + + private void collectRemainingPaths(TrieNode node, List path, Set duplicates, List> ans) { + if (duplicates.contains(node)) { + return; // Skip this subtree because it is marked for deletion + } + + if (!path.isEmpty()) { + ans.add(new ArrayList<>(path)); + } + + for (Map.Entry entry : node.children.entrySet()) { + path.add(entry.getKey()); + collectRemainingPaths(entry.getValue(), path, duplicates, ans); + path.remove(path.size() - 1); + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + List> paths1 = Arrays.asList( + Arrays.asList("a"), + Arrays.asList("c"), + Arrays.asList("d"), + Arrays.asList("a", "b"), + Arrays.asList("c", "b"), + Arrays.asList("d", "a") + ); + + List> result1 = sol.deleteDuplicateFolder(paths1); + for (List path : result1) { + System.out.println(path); + } + + List> paths2 = Arrays.asList( + Arrays.asList("a"), + Arrays.asList("c"), + Arrays.asList("a", "b"), + Arrays.asList("c", "b"), + Arrays.asList("a", "b", "x"), + Arrays.asList("a", "b", "x", "y"), + Arrays.asList("w"), + Arrays.asList("w", "y") + ); + + List> result2 = sol.deleteDuplicateFolder(paths2); + for (List path : result2) { + System.out.println(path); + } + } +}