forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelete-duplicate-folders-in-system.py
98 lines (87 loc) · 3.34 KB
/
delete-duplicate-folders-in-system.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Time: O(n * m * l + tlogt + l * t), m is the max number of folders in a path,
# , n is the number of paths
# , l is the max length of folder name
# , t is the size of trie
# Space: O(l * t)
import collections
class Solution(object):
def deleteDuplicateFolder(self, paths):
"""
:type paths: List[List[str]]
:rtype: List[List[str]]
"""
def mark(node, lookup, ids):
id_pairs = []
for subfolder, child in node.iteritems():
if child == "_del":
continue
node_id = mark(child, lookup, ids)
if subfolder not in ids:
ids[subfolder] = len(ids)
id_pairs.append((ids[subfolder], node_id))
id_pairs.sort()
node_id = ids[tuple(id_pairs)]
if node_id:
if node_id in lookup:
lookup[node_id]["_del"]
node["_del"]
else:
lookup[node_id] = node
return node_id
def sweep(node, path, result):
if path:
result.append(path[:])
for subfolder, child in node.iteritems():
if "_del" in child:
continue
path.append(subfolder)
sweep(child, path, result)
path.pop()
_trie = lambda: collections.defaultdict(_trie)
trie = _trie()
for path in paths:
reduce(dict.__getitem__, path, trie)
lookup, result = {}, []
ids = collections.defaultdict()
ids.default_factory = ids.__len__
mark(trie, lookup, ids)
sweep(trie, [], result)
return result
# Time: O(n * m * l + m * tlogt + l * t^2), m is the max number of folders in a path,
# , n is the number of paths
# , l is the max length of folder name
# , t is the size of trie
# Space: O(l * t^2)
import collections
class Solution2(object):
def deleteDuplicateFolder(self, paths):
"""
:type paths: List[List[str]]
:rtype: List[List[str]]
"""
def mark(node, lookup):
serialized_tree = "(" + "".join(subfolder + mark(child, lookup) for subfolder, child in sorted(node.iteritems()) if child != "_del") + ")"
if serialized_tree != "()":
if serialized_tree in lookup:
lookup[serialized_tree]["_del"]
node["_del"]
else:
lookup[serialized_tree] = node
return serialized_tree
def sweep(node, path, result):
if path:
result.append(path[:])
for subfolder, child in node.iteritems():
if "_del" in child:
continue
path.append(subfolder)
sweep(child, path, result)
path.pop()
_trie = lambda: collections.defaultdict(_trie)
trie = _trie()
for path in paths:
reduce(dict.__getitem__, path, trie)
lookup, result = {}, []
mark(trie, lookup)
sweep(trie, [], result)
return result