[Python3] Trie, DFS & Hashing
\nclass Node:\n    def __init__(self, ind=None):\n        self.ind = ind\n        self.d = defaultdict(Node)\n\n\nclass Solution:\n    def deleteDuplicateFolder
```\nclass Node:\n    def __init__(self, ind=None):\n        self.ind = ind\n        self.d = defaultdict(Node)\n\n\nclass Solution:\n    def deleteDuplicateFolder(self, paths: List[List[str]]) -> List[List[str]]:\n        root = Node()\n        for ind, path in enumerate(paths):\n            cur = root\n            for node in path:\n                cur = cur.d[node]\n            cur.ind = ind\n        \n        hashes = defaultdict(list)\n        rev = {}\n        # encode: 50 bits node, up to 500 * 50 = 25 000 bit path\n        def dfs(node, val, ind):\n            if not node:\n                return 0\n            childs = []\n            for child in node.d:\n                childs.append(dfs(node.d[child], child, node.d[child].ind))\n            cur = hash(tuple(sorted(childs)))\n            if ind >= 0:\n                hashes[cur].append(ind)\n                rev[ind] = cur\n            return hash((cur, val))            \n\n        dfs(root, \'a\', - 1)\n        mark = [False] * len(paths)\n\n        def dfs1(node, marked=False):\n            if node.ind is not None and node.d and len(hashes[rev[node.ind]]) > 1:\n                marked = True\n            if node.ind is not None:\n                mark[node.ind] = marked\n            for child in node.d:\n                dfs1(node.d[child], marked)\n\n        dfs1(root)\n\n        return [paths[i] for i in range(len(paths)) if not mark[i]]\n\n```
['Python3']