[Python] heapq ๋ผ์ด๋ธ๋ฌ๋ฆฌ
ํํ(heapq)๋ ํ์ด์ฌ ํ์ค๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ๋ชจ๋๋ก Heap ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ง์ํ๋ค.
์์ ์ด์งํธ๋ฆฌ ํํ๋ฅผ ํ๊ณ ์์ผ๋ฉฐ, ์ต์๊ฐ๊ณผ ์ต๋๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๋ค .
ํ์ด์ฌ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ต์ํ(min-heap)์ ์ ๊ณตํ๋ค. (๋ถ๋ชจ ๋ ธ๋์ ๊ฐ์ ์์ ๋ ธ๋์ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค.)
์ฃผ์ ๋ฉ์๋
heapq.heappush(heap, item)
ํ์ ์กฐ๊ฑด์ ์ ์งํ๋ฉด์ item์ heap์ push ํด์ค๋ค. ( O(logn) )
import heapq
heap = []
for i in range(10):
heapq.heappush(heap, i)
print(heap)
## [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
heapq.heappop(heap)
ํ์์ ๊ฐ์ฅ ์์ ์์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฐํํจ. ( O(logn) )
ํ์ด ๋น์ด์์ผ๋ฉด IndexError์ ๋ฐ์์ํด
import heapq
heap = [3,4,5,6]
print(heapq.heappop(heap))
### 3
print(heap)
### [4, 6, 5]
heapq.heapify(list)
๋ฆฌ์คํธ๋ฅผ ํ์ผ๋ก ๋ณํ์ํด ( O(n) )
๋ฆฌ์คํธ๋ฅผ ์ต์ ํ ์์ฑ์ ๊ฐ์ง๋๋ก ์ ๋ ฌํจ.
import heapq
list = [3,6,34,3,5,7,3,6,24,143]
heapq.heapify(list)
print(list)
##[3, 3, 3, 6, 5, 7, 34, 6, 24, 143]
heapq.nlargest ( n, heap, key=None )
heap์์ ๊ฐ์ฅ ํฐ n ๊ฐ์ ์์๋ฅผ ๋ฐํํจ. ( O(nlogn) )
key๋ฅผ ํตํด ์ ๋ ฌ๊ธฐ์ค์ ์ ํ ์ ์๋ค.
import heapq
heap = []
for i in range(10):
heapq.heappush(heap, i)
print(heapq.nlargest(3,heap))
## [9, 8, 7]
heapq.nsmallest(n, heap, key=None)
heap์์ ๊ฐ์ฅ ์์ n๊ฐ์ ์์๋ฅผ ๋ฐํ( O(nlogn) )
key๋ฅผ ํตํด ๊ธฐ์ค ์ค์ ๊ฐ๋ฅ
import heapq
heap = []
for i in range(10):
heapq.heappush(heap, i)
print(heapq.nsmallest(3,heap))
#[0, 1, 2]
ํ์ฉ ์์
1. ์ต๋ ํ ๊ตฌํ
import heapq
heap = []
number = [4,3,2,3,1]
for num in number:
heapq.heappush(heap, -num) #[-4, -3, -3, -2, -1]
for _ in range(len(heap)):
print(-heapq.heappop(heap), end = ", ")
## 4 3 3 2 1
ํ์ด์ฌ์์๋ ์ต๋ ํ์ ์ ๊ณตํ์ง ์๋๋ค.
ํ์ ๋ถํธ๋ฅผ ๋ณ๊ฒฝํ์ฌ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๊ฐ์ ์ ์ผ๋ก ์ต๋ ํ์ ๊ตฌํํ ์ ์๋ค.
2. ์ค์ ๊ฐ ์ฐพ๊ธฐ
import heapq
class MedianFinder:
def __init__(self):
self.left_heap = [] # ์ต๋ ํ
self.right_heap = [] # ์ต์ ํ
def add_num(self, num):
# ์ต๋ ํ์ ์ถ๊ฐ
heapq.heappush(self.left_heap, -num)
# ์ต๋ ํ์ ์ต๋๊ฐ์ ์ต์ ํ์ ์ด๋
heapq.heappush(self.right_heap, -heapq.heappop(self.left_heap))
# ์ต์ ํ์ ํฌ๊ธฐ๊ฐ ๋ ์ปค์ง๋ฉด ์ต์ ํ์ ์ต์๊ฐ์ ์ต๋ ํ์ผ๋ก ์ด๋
if len(self.right_heap) > len(self.left_heap):
heapq.heappush(self.left_heap, -heapq.heappop(self.right_heap))
def find_median(self):
if len(self.left_heap) > len(self.right_heap):
return -self.left_heap[0]
else:
return min(-self.left_heap[0], self.right_heap[0])
medianFinder = MedianFinder()
numbers = [4,1,3,4,5,6,4,3,3]
for num in numbers:
medianFinder.add_num(num)
print(f"Inserted {num}, current median is: {medianFinder.find_median()}")
"""
Inserted 4, current median is: 4
Inserted 1, current median is: 1
Inserted 3, current median is: 3
Inserted 4, current median is: 3
Inserted 5, current median is: 4
Inserted 6, current median is: 4
Inserted 4, current median is: 4
Inserted 3, current median is: 4
Inserted 3, current median is: 4
"""
์ต๋ ํ๊ณผ ์ต์ ํ์ ํ์ฉํ์ฌ ์ค์ ๊ฐ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ ์ ์๋ค.