-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathmaximum-points-activated-with-one-addition.py
More file actions
58 lines (53 loc) · 1.85 KB
/
maximum-points-activated-with-one-addition.py
File metadata and controls
58 lines (53 loc) · 1.85 KB
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
# Time: O(n)
# Space: O(n)
# union find
class Solution(object):
def maxActivated(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
class UnionFind(object): # Time: O(n * alpha(n)), Space: O(n)
def __init__(self, n):
self.set = range(n)
self.rank = [0]*n
self.size = [1]*n
def find_set(self, x):
stk = []
while self.set[x] != x: # path compression
stk.append(x)
x = self.set[x]
while stk:
self.set[stk.pop()] = x
return x
def union_set(self, x, y):
x, y = self.find_set(x), self.find_set(y)
if x == y:
return False
if self.rank[x] > self.rank[y]: # union by rank
x, y = y, x
elif self.rank[x] == self.rank[y]:
self.rank[y] += 1
self.set[x] = self.set[y]
self.size[y] += self.size[x]
return True
def total(self, x):
return self.size[self.find_set(x)]
N_DIM, N_ADD = 2, 1
uf = UnionFind(len(points))
lookup = [{} for _ in xrange(N_DIM)]
for i, p in enumerate(points):
for j in xrange(len(lookup)):
if p[j] in lookup[j]:
uf.union_set(i, lookup[j][p[j]])
else:
lookup[j][p[j]] = i
top = [0]*min(N_ADD+1, len(points))
for i in xrange(len(points)):
if uf.find_set(i) != i:
continue
s = uf.total(i)
for j in xrange(len(top)):
if s > top[j]:
top[j], s = s,top[j]
return sum(top)+N_ADD