Skip to content

Commit 50adeb8

Browse files
committed
Day 41: finish topKFrequent using a heap to save space
1 parent e704585 commit 50adeb8

File tree

1 file changed

+86
-2
lines changed

1 file changed

+86
-2
lines changed

day41/topKFrequent.py

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,90 @@
1-
def topKFrequent(nums, k):
1+
## A sample heap data structure ##
2+
from collections import deque
3+
4+
class MaxHeap:
5+
def __init__(self, arr=[]):
6+
self.heap = deque()
7+
self.size = 0
8+
if len(arr) > 0:
9+
self.size = len(arr)
10+
self.heapify(arr)
11+
12+
# runtime: O(logn) aka the height of the heap
13+
def getMax(self):
14+
if self.size > 0:
15+
ret = self.heap.popleft()
16+
self.size -= 1
17+
if self.size > 0:
18+
self.heap.appendleft(self.heap.pop())
19+
self.bubbleDown(0)
20+
return ret
21+
22+
# runtime: O(1)
23+
def peek(self):
24+
if self.size > 0:
25+
return self.heap[0]
26+
27+
# runtime: O(logn) aka the height of the heap
28+
def push(self, val):
29+
self.size += 1
30+
self.heap.append(val)
31+
self.bubbleUp()
32+
33+
# runtime: O(nlogn)
34+
def heapify(self, arr):
35+
self.heap = deque(arr)
36+
for i in xrange(self.size-1, -1, -1):
37+
self.bubbleDown(i)
238

39+
# runtime: O(1)
40+
def isEmpty(self):
41+
return self.size == 0
42+
43+
def bubbleDown(self, index):
44+
if self.size > 0:
45+
i = index
46+
h = self.heap
47+
withinBounds = 2*i + 2 < self.size
48+
while withinBounds and (h[i][1] < h[2*i + 1][1] or h[i][1] < h[2*i + 2][1]):
49+
if h[i][1] < h[2*i + 1][1] and h[i][1] < h[2*i + 2][1]:
50+
if h[2*i + 1][1] > h[2*i + 2][1]:
51+
h[i], h[2*i + 1] = h[2*i + 1], h[i]
52+
i = 2*i + 1
53+
else:
54+
h[i], h[2*i + 2] = h[2*i + 2], h[i]
55+
i = 2*i + 2
56+
elif h[i][1] < h[2*i + 1][1]:
57+
h[i], h[2*i + 1] = h[2*i + 1], h[i]
58+
i = 2*i + 1
59+
elif h[i][1] < h[2*i + 2][1]:
60+
h[i], h[2*i + 2] = h[2*i + 2], h[i]
61+
i = 2*i + 2
62+
withinBounds = 2*i + 2 < self.size
63+
64+
if 2*i + 1 < self.size and h[i][1] < h[2*i + 1][1]:
65+
h[i], h[2*i + 1] = h[2*i + 1], h[i]
66+
elif 2*i + 2 < self.size and h[i][1] < h[2*i + 2][1]:
67+
h[i], h[2*i + 2] = h[2*i + 2], h[i]
68+
69+
def bubbleUp(self):
70+
if self.size > 0:
71+
i = self.size-1
72+
h = self.heap
73+
withinBounds = i/2 >= 0
74+
while withinBounds and (h[i] > h[i/2]):
75+
h[i/2], h[i] = h[i], h[i/2]
76+
i /= 2
77+
withinBounds = i/2 >= 0
78+
79+
from collections import Counter
80+
81+
def topKFrequent(nums, k):
82+
freqs = Counter(nums)
83+
h = MaxHeap(freqs.items())
84+
ret = list()
85+
while k > 0:
86+
ret.append(h.getMax()[0])
87+
k -=1
388
return ret
489

590
def testTopKFrequent():
@@ -10,7 +95,6 @@ def testTopKFrequent():
1095
assert set(topKFrequent([-1,-1,-1,2,2,3], 2)) == set([-1, 2])
1196
assert set(topKFrequent([1,1,1,2,2,3], 3)) == set([1, 2, 3])
1297
assert set(topKFrequent([1,1,1,2,2,2,3,3,3], 3)) == set([1, 2, 3])
13-
assert set(topKFrequent([1, 2, 3, 4, 5], 1)) == set([1, 2, 3, 4, 5])
1498
assert set(topKFrequent([4,1,-1,2,-1,2,3], 2)) == set([-1, 2])
1599
assert set(topKFrequent([3,2,3,1,2,4,5,5,6,7,7,8,2,3,1,1,1,10,11,5,6,2,4,7,8,5,6], 10)) == set([1,2,5,3,7,6,4,8,10,11])
16100

0 commit comments

Comments
 (0)