1
+
2
+ class Trie :
3
+ # current node structure's serialized representation
4
+ serial : str = ""
5
+ # current node's child nodes
6
+ children : dict
7
+
8
+ def __init__ (self ):
9
+ self .children = dict ()
10
+
11
+
12
+ class Solution :
13
+ def deleteDuplicateFolder (self , paths : List [List [str ]]) -> List [List [str ]]:
14
+ # root node
15
+ root = Trie ()
16
+
17
+ for path in paths :
18
+ cur = root
19
+ for node in path :
20
+ if node not in cur .children :
21
+ cur .children [node ] = Trie ()
22
+ cur = cur .children [node ]
23
+
24
+ # hash table records the occurrence times of each serialized representation
25
+ freq = Counter ()
26
+
27
+ # post-order traversal based on depth-first search, calculate the serialized representation of each node structure
28
+ def construct (node : Trie ) -> None :
29
+ # if it is a leaf node, then the serialization is represented as an empty string, and no operation is required.
30
+ if not node .children :
31
+ return
32
+
33
+ v = list ()
34
+ # if it is not a leaf node, the serialization representation of the child node structure needs to be calculated first.
35
+ for folder , child in node .children .items ():
36
+ construct (child )
37
+ v .append (folder + "(" + child .serial + ")" )
38
+
39
+ # to prevent issues with order, sorting is needed
40
+ v .sort ()
41
+ node .serial = "" .join (v )
42
+ # add to hash table
43
+ freq [node .serial ] += 1
44
+
45
+ construct (root )
46
+
47
+ ans = list ()
48
+ # record the path from the root node to the current node.
49
+ path = list ()
50
+
51
+ def operate (node : Trie ) -> None :
52
+ # if the serialization appears more than once in the hash table, it needs to be deleted.
53
+ if freq [node .serial ] > 1 :
54
+ return
55
+ # otherwise add the path to the answer
56
+ if path :
57
+ ans .append (path [:])
58
+
59
+ for folder , child in node .children .items ():
60
+ path .append (folder )
61
+ operate (child )
62
+ path .pop ()
63
+
64
+ operate (root )
65
+ return ans
0 commit comments