Serialized Tree Traversal + Hashmap | Clean and clear solution
Main idea is simple: \n\n1) Build:   Build the tree using Trie. Since the nodes are not simply characters but strings so use unordered_map instead of array.\n2)
Main idea is simple: \n\n1) **Build:**   Build the tree using Trie. Since the nodes are not simply characters but strings so use unordered_map instead of array.\n2) **Count:** Run a counter (dfs) function to store the count of similar subtrees.\n3) **Destroy:** Do another dfs to mark the same hash (which occur more than once) as isCleared to not count them while building the answer.\n4) **Collect:** Run a final dfs to store the paths in final answer.\n\nThis implementation is pretty naive but its easy to understand so thought maybe I should post. Any improvements are welcome :)\n\n```\nclass Solution {\npublic:\n    class Node {\n    public:\n        unordered_map<string, Node*> children;\n        string val;\n        bool isEnd;\n        bool isCleared;\n        Node(): isEnd(false), isCleared(false) {}\n        Node(const string& s): val(s), isEnd(false), isCleared(false) {}\n    };\n    \n    unordered_map<string, int> store;\n    string counter(Node* root) { //counter function to count the subtrees\n        if(!root) return "";\n        \n        string hash;\n        for(auto& nex: root->children) {\n            string temphash = counter(nex.second);\n            temphash += nex.first;\n            hash += "#" + temphash;\n        }\n        \n        // cout << "In collect | hash: " << hash << endl;\n        \n        if(hash.size()) // just to get rid of empty hashes\n            store[hash]++;\n        return hash;\n    }\n    \n    string destroy(Node* root) {\n        if(!root) return "";\n        \n        string hash;\n        for(auto& nex: root->children) {\n            string temphash = destroy(nex.second);\n            temphash += nex.first;\n            hash += "#" + temphash;\n        }\n        \n        if(store[hash] > 1) { // mark the root as "isCleared" if the same subtree occurs more than once\n            // cout << "In destroy | hash: " << hash << " removing: " << root->val << endl;\n            root->isCleared = true;\n        }\n        \n        return hash;\n    }\n    \n    void collect(Node* root, vector<string>& temp, vector<vector<string>>& ans) {\n        if(!root) return;\n        if(root->isCleared) return;\n        \n        if(root->children.size() == 0) {\n            if(temp.size())\n                ans.push_back(temp);\n            return;\n        }\n        \n        if(root->isEnd) //only push the current path in if this path exists in paths\n            ans.push_back(temp);\n        \n        for(auto& nex: root->children) {\n            temp.push_back(nex.first);\n            collect(nex.second, temp, ans);\n            temp.pop_back();\n        }\n    }\n    \n    vector<vector<string>> deleteDuplicateFolder(vector<vector<string>>& paths) {\n        Node* root = new Node("\\\\");\n        \n\t\t//build the tree\n        for(auto& path: paths) {\n            Node* temp = root;\n            for(auto& val: path) {\n                if(temp->children[val] == NULL)\n                    temp->children[val] = new Node(val);\n                temp = temp->children[val];\n            }\n            temp->isEnd = true;\n        }\n        \n        counter(root);\n        destroy(root);\n        \n        vector<vector<string>> ans;\n        vector<string> temp;\n        \n        collect(root, temp, ans);\n        \n        return ans;\n    }\n};\n```
['Depth-First Search', 'Trie', 'C']