@@ -130,24 +130,251 @@ tags:
130130
131131``` python
132132
133+ class Trie :
134+ serial: str = " "
135+ children: dict
136+
137+ def __init__ (self ):
138+ self .children = dict ()
139+
140+
141+ class Solution :
142+ def deleteDuplicateFolder (self , paths : List[List[str ]]) -> List[List[str ]]:
143+ root = Trie()
144+ for path in paths:
145+ cur = root
146+ for node in path:
147+ if node not in cur.children:
148+ cur.children[node] = Trie()
149+ cur = cur.children[node]
150+ freq = Counter()
151+ def construct (node : Trie) -> None :
152+ if not node.children:
153+ return
154+ v = list ()
155+ for folder, child in node.children.items():
156+ construct(child)
157+ v.append(folder + " (" + child.serial + " )" )
158+ v.sort()
159+ node.serial = " " .join(v)
160+ freq[node.serial] += 1
161+ construct(root)
162+ ans = list ()
163+ path = list ()
164+ def operate (node : Trie) -> None :
165+ if freq[node.serial] > 1 :
166+ return
167+ if path:
168+ ans.append(path[:])
169+ for folder, child in node.children.items():
170+ path.append(folder)
171+ operate(child)
172+ path.pop()
173+ operate(root)
174+ return ans
175+
133176```
134177
135178#### Java
136179
137180``` java
138181
182+ class Solution {
183+
184+ class Trie {
185+
186+ String serial;
187+ Map<String , Trie > children = new HashMap<> ();
188+ }
189+
190+ public List<List<String > > deleteDuplicateFolder (List<List<String > > paths ) {
191+ Trie root = new Trie ();
192+ for (List<String > path : paths) {
193+ Trie cur = root;
194+ for (String node : path) {
195+ cur. children. putIfAbsent(node, new Trie ());
196+ cur = cur. children. get(node);
197+ }
198+ }
199+
200+ Map<String , Integer > freq = new HashMap<> ();
201+ construct(root, freq);
202+ List<List<String > > ans = new ArrayList<> ();
203+ List<String > path = new ArrayList<> ();
204+ operate(root, freq, path, ans);
205+ return ans;
206+ }
207+
208+ private void construct (Trie node , Map<String , Integer > freq ) {
209+ if (node. children. isEmpty()) return ;
210+
211+ List<String > v = new ArrayList<> ();
212+ for (Map . Entry<String , Trie > entry : node. children. entrySet()) {
213+ construct(entry. getValue(), freq);
214+ v. add(entry. getKey() + " (" + entry. getValue(). serial + " )" );
215+ }
216+
217+ Collections . sort(v);
218+ StringBuilder sb = new StringBuilder ();
219+ for (String s : v) {
220+ sb. append(s);
221+ }
222+ node. serial = sb. toString();
223+ freq. put(node. serial, freq. getOrDefault(node. serial, 0 ) + 1 );
224+ }
225+
226+ private void operate (
227+ Trie node ,
228+ Map<String , Integer > freq ,
229+ List<String > path ,
230+ List<List<String > > ans
231+ ) {
232+ if (freq. getOrDefault(node. serial, 0 ) > 1 ) return ;
233+
234+ if (! path. isEmpty()) {
235+ ans. add(new ArrayList<> (path));
236+ }
237+
238+ for (Map . Entry<String , Trie > entry : node. children. entrySet()) {
239+ path. add(entry. getKey());
240+ operate(entry. getValue(), freq, path, ans);
241+ path. remove(path. size() - 1 );
242+ }
243+ }
244+ }
245+
139246```
140247
141248#### C++
142249
143250``` cpp
144251
252+ struct Trie {
253+ string serial;
254+ unordered_map<string, Trie* > children;
255+ };
256+
257+ class Solution {
258+ public:
259+ vector<vector<string >> deleteDuplicateFolder(
260+ vector<vector<string >>& paths) {
261+ Trie* root = new Trie();
262+
263+ for (const vector<string>& path : paths) {
264+ Trie* cur = root;
265+ for (const string& node : path) {
266+ if (!cur->children.count(node)) {
267+ cur->children[node] = new Trie();
268+ }
269+ cur = cur->children[node];
270+ }
271+ }
272+ unordered_map<string, int > freq;
273+ function<void (Trie*)> construct = [&](Trie* node) {
274+ if (node->children.empty()) {
275+ return;
276+ }
277+
278+ vector<string> v;
279+ for (const auto& [folder, child] : node->children) {
280+ construct (child);
281+ v.push_back(folder + "(" + child->serial + ")");
282+ }
283+ sort(v.begin(), v.end());
284+ for (string& s : v) {
285+ node->serial += move(s);
286+ }
287+ ++freq[ node->serial] ;
288+ };
289+
290+ construct (root);
291+
292+ vector<vector<string>> ans;
293+ vector<string> path;
294+
295+ function<void(Trie*)> operate = [&](Trie* node) {
296+ if (freq[node->serial] > 1) {
297+ return;
298+ }
299+ if (!path.empty()) {
300+ ans.push_back(path);
301+ }
302+ for (const auto& [folder, child] : node->children) {
303+ path.push_back(folder);
304+ operate (child);
305+ path.pop_back();
306+ }
307+ };
308+
309+ operate (root);
310+ return ans;
311+ }
312+ };
313+
145314```
146315
147316#### Go
148317
149318``` go
150319
320+ type Trie struct {
321+ serial string
322+ children map [string ]*Trie
323+ }
324+
325+ func deleteDuplicateFolder (paths [][]string ) [][]string {
326+ root := &Trie{children: make (map [string ]*Trie)}
327+ for _ , path := range paths {
328+ cur := root
329+ for _ , node := range path {
330+ if _ , ok := cur.children [node]; !ok {
331+ cur.children [node] = &Trie{children: make (map [string ]*Trie)}
332+ }
333+ cur = cur.children [node]
334+ }
335+ }
336+
337+ freq := make (map [string ]int )
338+ var construct func (*Trie)
339+ construct = func (node *Trie) {
340+ if len (node.children ) == 0 {
341+ return
342+ }
343+ v := make ([]string , 0 , len (node.children ))
344+ for folder , child := range node.children {
345+ construct (child)
346+ v = append (v, folder+" (" +child.serial +" )" )
347+ }
348+ sort.Strings (v)
349+ node.serial = strings.Join (v, " " )
350+ freq[node.serial ]++
351+ }
352+ construct (root)
353+
354+ ans := make ([][]string , 0 )
355+ path := make ([]string , 0 )
356+ var operate func (*Trie)
357+ operate = func (node *Trie) {
358+ if freq[node.serial ] > 1 {
359+ return
360+ }
361+ if len (path) > 0 {
362+ tmp := make ([]string , len (path))
363+ copy (tmp, path)
364+ ans = append (ans, tmp)
365+ }
366+ for folder , child := range node.children {
367+ path = append (path, folder)
368+ operate (child)
369+ path = path[:len (path)-1 ]
370+ }
371+ }
372+ operate (root)
373+
374+ return ans
375+ }
376+
377+
151378```
152379
153380<!-- tabs:end -->
0 commit comments