forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
design-a-file-sharing-system.py
124 lines (109 loc) · 3.24 KB
/
design-a-file-sharing-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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Time: ctor: O(1)
# join: O(logu + c), u is the number of total joined users
# leave: O(logu + c), c is the number of chunks
# request: O(u)
# Space: O(u * c)
import heapq
# "u ~= n" solution, n is the average number of users who own the chunk
class FileSharing(object):
def __init__(self, m):
"""
:type m: int
"""
self.__users = []
self.__lookup = set()
self.__min_heap = []
def join(self, ownedChunks):
"""
:type ownedChunks: List[int]
:rtype: int
"""
if self.__min_heap:
userID = heapq.heappop(self.__min_heap)
else:
userID = len(self.__users)+1
self.__users.append(set())
self.__users[userID-1] = set(ownedChunks)
self.__lookup.add(userID)
return userID
def leave(self, userID):
"""
:type userID: int
:rtype: None
"""
if userID not in self.__lookup:
return
self.__lookup.remove(userID)
self.__users[userID-1] = []
heapq.heappush(self.__min_heap, userID)
def request(self, userID, chunkID):
"""
:type userID: int
:type chunkID: int
:rtype: List[int]
"""
result = []
for u, chunks in enumerate(self.__users, 1):
if chunkID not in chunks:
continue
result.append(u)
if not result:
return
self.__users[userID-1].add(chunkID)
return result
# Time: ctor: O(1)
# join: O(logu + c), u is the number of total joined users
# leave: O(logu + c), c is the number of chunks
# request: O(nlogn) , n is the average number of users who own the chunk
# Space: O(u * c + m), m is the total number of unique chunks
import collections
import heapq
# "u >> n" solution
class FileSharing2(object):
def __init__(self, m):
"""
:type m: int
"""
self.__users = []
self.__lookup = set()
self.__chunks = collections.defaultdict(set)
self.__min_heap = []
def join(self, ownedChunks):
"""
:type ownedChunks: List[int]
:rtype: int
"""
if self.__min_heap:
userID = heapq.heappop(self.__min_heap)
else:
userID = len(self.__users)+1
self.__users.append(set())
self.__users[userID-1] = set(ownedChunks)
self.__lookup.add(userID)
for c in ownedChunks:
self.__chunks[c].add(userID)
return userID
def leave(self, userID):
"""
:type userID: int
:rtype: None
"""
if userID not in self.__lookup:
return
for c in self.__users[userID-1]:
self.__chunks[c].remove(userID)
self.__lookup.remove(userID)
self.__users[userID-1] = []
heapq.heappush(self.__min_heap, userID)
def request(self, userID, chunkID):
"""
:type userID: int
:type chunkID: int
:rtype: List[int]
"""
result = sorted(self.__chunks[chunkID])
if not result:
return
self.__users[userID-1].add(chunkID)
self.__chunks[chunkID].add(userID)
return result