C++ || Trie || HashMap || OOPs || Serialization
\n#define F first\n#define S second\n\nclass Trie {\nprivate:\n    struct trieNode{\n        map<string,trieNode*> child;\n        string word="";\n    }; \n   
```\n#define F first\n#define S second\n\nclass Trie {\nprivate:\n    struct trieNode{\n        map<string,trieNode*> child;\n        string word="";\n    }; \n    trieNode* root;\n    vector<vector<string>> res;\n    unordered_map<string,vector<trieNode*>> m1;\n    unordered_set<trieNode*> vis;\npublic:   \n    Trie() {\n        root=new trieNode();\n    }\n    \n    /** Inserts a word into the trie. */\n    void insert(vector<string> &word) {\n        trieNode* temp=root;\n        for(auto &i: word){\n            string ch=i;\n            if(temp->child.find(ch)== temp->child.end()){\n                temp->child[ch]= new trieNode();\n            }\n            temp=temp->child[ch];\n        }\n        \n    }\n    void serialize() {\n        trieNode* temp=root;\n        \n        for(auto &i:temp->child){\n            serialize(i.S,i.F);\n        }\n    }\n    \n    //Encode the subtree . Just make sure to use different delimiters i.e \'$\' for combining encoded string of childs and \'#\' for combining encoded string of subtree with parent \n    string serialize(trieNode* temp,const string &par) {\n     \n        string subtree="";\n       \n        for(auto &i:temp->child){\n\n            string child=serialize(i.S,i.F);\n            if(child!=""){\n                subtree+=child;\n                subtree+=\'$\';\n            }\n        }\n        if(!subtree.empty()){\n            temp->word=subtree;\n            m1[subtree].push_back(temp);\n        }\n            \n        string tt=par;\n        tt+=\'#\';\n        if(!subtree.empty())\n            tt+=subtree;\n        return tt;\n        \n    }    \n    void mark(){\n        for(auto &i:m1){\n            if((int)i.S.size()>1){\n                for(auto &j:i.S){\n                    vis.insert(j);\n                }\n            }\n        }\n    }\n    void solve(trieNode* temp,const string &ch,vector<string> &ans){\n        if(vis.find(temp)!=vis.end()){\n            return;\n        }\n        ans.push_back(ch);\n        res.push_back(ans);\n        for(auto &i: temp->child){\n            solve(i.S,i.F,ans);\n        }\n        ans.pop_back();\n    }\n    void solve(){\n        vector<string> ans;\n        trieNode* temp=root;\n        for(auto &i:temp->child){\n            solve(i.S,i.F,ans);\n        }\n    }\n    \n    \n    vector<vector<string>> answer(){\n        return res;\n    }\n    \n};\nclass Solution {\npublic:\n    vector<vector<string>> deleteDuplicateFolder(vector<vector<string>>& paths) {\n        Trie* obj= new Trie();\n        for(auto &i:paths){\n            obj->insert(i);\n        }\n        obj->serialize();\n        obj->mark();\n        obj->solve();\n        return obj->answer();\n        \n    }\n};\n```
[]