Java | HashMap | Trie | Backtracking | easy to understand
If you know HashMaps and Trie and Backtracking, it should be easy for you to understand the solution\n\njava\nclass Solution {\n    static class Node {\n       
If you know HashMaps and Trie and Backtracking, it should be easy for you to understand the solution\n\n```java\nclass Solution {\n    static class Node {\n        String name;\n        Map<String, Node> childern = new HashMap<>();\n\n        private String hashCode = null;\n\n        public Node(String _name) {\n            name = _name;\n        }\n\n        public void add(List<String> path) {\n            Node cur = this;\n            for (String file : path) {\n                if (!cur.childern.containsKey(file)) {\n                    cur.childern.put(file, new Node(file));\n                }\n                cur = cur.childern.get(file);\n            }\n        }\n\n        public String getHashCode() {\n            if(hashCode == null) {\n                hashCode = computeHash();\n            }\n\n            return hashCode;\n        }\n\n        private String computeHash() {\n            StringBuilder sb = new StringBuilder();\n            List<Node> nodes = new ArrayList<>();\n            \n            for(Node n: childern.values()) {\n                nodes.add(n);\n            }\n\n            if(nodes.size() == 0)\n                return null;\n\n            nodes.sort((a, b) -> a.name.compareTo(b.name));\n\n            for (Node n: nodes){\n                sb.append(\'(\');\n                sb.append(n.name + n.getHashCode());\n                sb.append(\')\');\n            }\n\n            return sb.toString();\n        }\n    }\n\n    private static void getGoodFiles(Node node, Map<String, Integer> occurs, List<String> cur, List<List<String>> ans) {\n        if(occurs.containsKey(node.getHashCode()) && occurs.get(node.getHashCode()) > 1) return;\n\n        cur.add(node.name);\n        ans.add(new ArrayList<>(cur));\n\n        for(Node n: node.childern.values())\n            getGoodFiles(n, occurs, cur, ans);\n\n        cur.remove(cur.size()-1);\n    }\n\n    private static void findOccurs(Node node, Map<String, Integer> occurs) {\n        String key = node.getHashCode();\n        if(key != null) {\n            occurs.put(key, occurs.getOrDefault(node.getHashCode(), 0)+1);\n        }\n\n        for(Node n: node.childern.values()) {\n            findOccurs(n, occurs);\n        }\n    }\n\n\n    static Node root;\n\n    public static List<List<String>> deleteDuplicateFolder(List<List<String>> paths) {\n        root = new Node("");\n        for (List<String> path : paths)\n            root.add(path);\n\n        Map<String, Integer> occurs = new HashMap<>();\n        findOccurs(root, occurs);\n\n        List<List<String>> ans = new ArrayList<>();\n        for(Node n: root.childern.values())\n            getGoodFiles(n, occurs, new ArrayList<>(), ans);\n\n        return ans;\n    }\n}\n```
[]