-
Notifications
You must be signed in to change notification settings - Fork 94
/
Median.py
163 lines (137 loc) · 4.9 KB
/
Median.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
"""
The median of M numbers is defined as the middle number after sorting them in order, if M is odd. Or it is the average
of the middle 2 numbers (again after sorting), if M is even. You have an empty number list at first. Then you can add in
or remove some number from the list. For each add or remove operation, output the median of numbers in the list.
Example :
For a set of M = 5 numbers {9, 2, 8, 4, 1} the median is the third number in sorted set {1, 2, 4, 8, 9} which is 4.
Similarly, for a set of M = 4, {5, 2, 10, 4}, the median is the average of second and the third element in the sorted
set {2, 4, 5, 10} which is (4+5)/2 = 4.5.
Input:
The first line is an integer N that indicates the number of operations. Each of the next N lines is either a x or r x .
a x indicates that x is added to the set, and r x indicates that x is removed from the set.
"""
__author__ = 'Danyang'
# from Queue import PriorityQueue # PriorityQueue does not support removal
import heapq
class Solution_TLE(object):
def __init__(self):
self.heap = []
def solve(self, cipher):
"""
Heap
:param cipher: the cipher
"""
op = cipher[0]
num = int(cipher[1])
if op == "r":
try:
self.heap.remove(num)
except ValueError:
return "Wrong!"
heapq.heapify(self.heap)
else:
heapq.heappush(self.heap, num)
length = len(self.heap)
if not self.heap:
return "Wrong!"
pq = list(self.heap)
pq = [heapq.heappop(pq) for _ in xrange(length)]
if length & 1 == 0:
return 0.5 * (pq[length / 2 - 1] + pq[length / 2])
else:
return pq[length / 2]
class Solution_TLE2(object):
def __init__(self):
self.min_heap = []
self.max_heap = [] # no max heap in Python
def solve(self, cipher):
"""
Median_Heap
Still TLE
Notice that 6, 7, 8 test cases time out
:param cipher: the cipher
"""
op = cipher[0]
num = int(cipher[1])
if op == "r":
try:
# if self.max_heap and -num>self.max_heap[0]:
if self.min_heap and num >= self.min_heap[0]:
self.min_heap.remove(num)
heapq.heapify(self.min_heap)
else:
self.max_heap.remove(-num)
heapq.heapify(self.max_heap)
if not self.min_heap and not self.max_heap:
return "Wrong!"
self.__balance()
except ValueError:
return "Wrong!"
else:
# if self.max_heap and -num>self.max_heap[0]:
if self.min_heap and num >= self.min_heap[0]:
heapq.heappush(self.min_heap, num)
else:
heapq.heappush(self.max_heap, -num)
self.__balance()
# return "%g"%self.__get_median() # %g rather than %s to avoid trailing zero # general format # fail
output = str(self.__get_median())
if output[-2:] == ".0":
output = output[:-2]
return output
def __balance(self):
if len(self.min_heap) > len(self.max_heap) + 1:
item = heapq.heappop(self.min_heap)
heapq.heappush(self.max_heap, -item)
return
if len(self.max_heap) > len(self.min_heap) + 1:
item = heapq.heappop(self.max_heap)
heapq.heappush(self.min_heap, -item)
return
def __get_median(self):
if len(self.min_heap) == len(self.max_heap):
return 0.5 * (self.min_heap[0] + (-1) * self.max_heap[0])
elif len(self.min_heap) > len(self.max_heap):
return self.min_heap[0]
else:
return -self.max_heap[0]
from bisect import bisect_left
class Solution(object):
def __init__(self):
self.A = []
def solve(self, cipher):
"""
bisect
"""
op = cipher[0]
val = int(cipher[1])
pos = bisect_left(self.A, val)
if op == "r":
if pos >= len(self.A) or self.A[pos] != val:
return "Wrong!"
else:
del (self.A[pos])
else: # "a"
self.A.insert(pos, val)
l = len(self.A)
if l == 0:
return "Wrong!"
elif l & 1 == 1:
return self.A[l / 2]
else:
output = str(0.5 * (self.A[l / 2 - 1] + self.A[l / 2]))
if output[-2:] == ".0":
output = output[:-2]
return output
if __name__ == "__main__":
import sys
f = open("0.in", "r")
# f = sys.stdin
testcases = int(f.readline().strip())
solution = Solution()
for t in xrange(testcases):
# construct cipher
cipher = f.readline().strip().split(' ')
# solve
s = "%s\n" % (solution.solve(cipher))
print s,