trie + subtree hashing
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\n/**\n * @param {string[][]} paths\n * @return {string[][]}\n */\nclass TrieNode {\n    constructor() {\n        this.children = new Map()\n        this.del = false\n        this.val = \'\'\n    }\n}\nclass Trie {\n    constructor() {\n        this.root = new TrieNode()\n    }\n    insert(path) {\n        let node = this.root\n        for (const folder of path) {\n            if (!node.children.has(folder)) {\n                node.children.set(folder, new TrieNode())\n                node.val = folder\n            }\n            node = node.children.get(folder)\n        }\n    }\n}\nvar deleteDuplicateFolder = function (paths) {\n    paths.sort()\n    let trie = new Trie()\n    for (const path of paths) {\n        trie.insert(path)\n    }\n    let root = trie.root\n    let map = new Map()\n    function dfs(node) {\n        if (node.children.size === 0) return node.val\n        let output = \'\'\n        for (const [k, child] of node.children.entries()) {\n            output += `${k}${dfs(child)}`\n        }\n        if (output) {\n            if (!map.has(output)) {\n                map.set(output, [])\n            }\n            map.get(output).push(node)\n        }\n        return node.val + output\n\n    }\n    dfs(root)\n    for (const [k, arr] of map.entries()) {\n        if (arr.length > 1) {\n            for (const node of arr) {\n                node.del = true\n            }\n        }\n    }\n    let output = []\n    function dfs2(node, path) {\n        for (const [k, child] of node.children.entries()) {\n            if (!child.del) {\n\n                dfs2(child, [...path, k])\n            }\n        }\n        if (path.length) {\n            output.push([...path])\n        }\n\n    }\n    dfs2(root, [])\n    return output\n};\n```
['JavaScript']