forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
design-excel-sum-formula.py
89 lines (70 loc) · 2.38 KB
/
design-excel-sum-formula.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
# Time: set: O((r * c)^2)
# get: O(1)
# sum: O((r * c)^2)
# Space: O(r * c)
import collections
class Excel(object):
def __init__(self, H, W):
"""
:type H: int
:type W: str
"""
self.__exl = [[0 for _ in xrange(ord(W)-ord('A')+1)] \
for _ in xrange(H+1)]
self.__fward = collections.defaultdict(lambda : collections.defaultdict(int))
self.__bward = collections.defaultdict(set)
def set(self, r, c, v):
"""
:type r: int
:type c: str
:type v: int
:rtype: void
"""
self.__reset_dependency(r, c)
self.__update_others(r, c, v)
def get(self, r, c):
"""
:type r: int
:type c: str
:rtype: int
"""
return self.__exl[r][ord(c) - ord('A')]
def sum(self, r, c, strs):
"""
:type r: int
:type c: str
:type strs: List[str]
:rtype: int
"""
self.__reset_dependency(r, c)
result = self.__calc_and_update_dependency(r, c, strs)
self.__update_others(r, c, result)
return result
def __reset_dependency(self, r, c):
key = (r, c)
if key in self.__bward.keys():
for k in self.__bward[key]:
self.__fward[k].pop(key, None)
self.__bward[key] = set()
def __calc_and_update_dependency(self, r, c, strs):
result = 0
for s in strs:
s, e = s.split(':')[0], s.split(':')[1] if ':' in s else s
left, right, top, bottom = ord(s[0])-ord('A'), ord(e[0])-ord('A'), int(s[1:]), int(e[1:])
for i in xrange(top, bottom+1):
for j in xrange(left, right+1):
result += self.__exl[i][j]
self.__fward[(i, chr(ord('A')+j))][(r, c)] += 1
self.__bward[(r, c)].add((i, chr(ord('A')+j)))
return result
def __update_others(self, r, c, v):
prev = self.__exl[r][ord(c)-ord('A')]
self.__exl[r][ord(c)-ord('A')] = v
q = collections.deque()
q.append(((r, c), v-prev))
while q:
key, diff = q.popleft()
if key in self.__fward:
for k, count in self.__fward[key].iteritems():
q.append((k, diff*count))
self.__exl[k[0]][ord(k[1])-ord('A')] += diff*count