Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b5e51ad

Browse files
authored
Add files via upload
1 parent 09aaf78 commit b5e51ad

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

‎Two_Heaps/median_sliding_window.py‎

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
from heapq import *
2+
3+
def median_sliding_window(nums, k):
4+
5+
# To store medians
6+
medians = []
7+
8+
# To track values to be removed from heaps
9+
outgoing_nums = {}
10+
11+
# Max heap for small values and min heap for large values
12+
max_heap = []
13+
min_heap = []
14+
15+
# Initialize max heap by multiplying each element by -1
16+
for i in range(k):
17+
heappush(max_heap, -1 * nums[i])
18+
19+
# Tranfer top half of numbers from max to min heap (and update sign)
20+
for i in range(k // 2):
21+
element = heappop(max_heap)
22+
heappush(min_heap, -1 * element)
23+
24+
# Variable to keep heaps balanced
25+
balance = 0
26+
27+
i = k
28+
29+
while True:
30+
31+
# Check if the window size is odd
32+
if (k & 1) == 1:
33+
medians.append(float(max_heap[0] * -1))
34+
else:
35+
medians.append((float(max_heap[0] * -1) + float(min_heap[0])) * 0.5)
36+
37+
# Break the loop if all elements have been processed
38+
if i >= len(nums):
39+
break
40+
41+
# Set outgoing number
42+
out_num = nums[i - k]
43+
44+
# Set incoming number
45+
in_num = nums[i]
46+
i += 1
47+
48+
# If outgoing number is from max heap
49+
if out_num <= (max_heap[0] * -1):
50+
balance -= 1
51+
else:
52+
balance += 1
53+
54+
# Add/update the outgoing number in the hash map
55+
if out_num in outgoing_nums:
56+
outgoing_nums[out_num] = outgoing_nums[out_num] + 1
57+
else:
58+
outgoing_nums[out_num] = 1
59+
60+
# Check if the incoming number is less than the top of max heap
61+
if max_heap and in_num <= (max_heap[0] * -1):
62+
balance += 1
63+
heappush(max_heap, in_num * -1)
64+
# Otherwise, add to the min heap
65+
else:
66+
balance -= 1
67+
heappush(min_heap, in_num)
68+
69+
# Rebalance the heaps
70+
if balance < 0:
71+
heappush(max_heap, (-1 * min_heap[0]))
72+
heappop(min_heap)
73+
elif balance > 0:
74+
heappush(min_heap, (-1 * max_heap[0]))
75+
heappop(max_heap)
76+
77+
# Reset balance to zero
78+
balance = 0
79+
80+
# Remove invalid numbers in hash map from top of max heap
81+
while(max_heap[0] * -1) in outgoing_nums and (outgoing_nums[max_heap[0] * -1] > 0):
82+
outgoing_nums[max_heap[0] * -1] = outgoing_nums[max_heap[0] * -1] - 1
83+
heappop(max_heap)
84+
85+
# Remove invalid number in hash map from top of min heap
86+
while min_heap and min_heap[0] in outgoing_nums and (outgoing_nums[min_heap[0]] > 0):
87+
outgoing_nums[min_heap[0]] = outgoing_nums[min_heap[0]] - 1
88+
heappop(min_heap)
89+
90+
return medians
91+
92+
93+
94+
# Time Complexity = O(nlogn)
95+
# Space Complexity = O(n)
96+
97+
98+
99+
###############################################################
100+
101+
102+
103+
def main():
104+
input = (
105+
([3, 1, 2, -1, 0, 5, 8],4),
106+
([1, 2], 1),
107+
([4, 7, 2, 21], 2),
108+
([22, 23, 24, 56, 76, 43, 121, 1, 2, 0, 0, 2, 3, 5], 5),
109+
([1, 1, 1, 1, 1], 2))
110+
x = 1
111+
for i in input:
112+
print(x, ".\tInput array: ", i[0], ", k = ", i[1], sep = "")
113+
print("\tMedians: ", median_sliding_window(i[0], i[1]), sep = "")
114+
print(100*"-", "\n", sep = "")
115+
x += 1
116+
117+
118+
if __name__ == "__main__":
119+
main()
120+
121+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /