파이썬에서 heapq 모듈로 최소 힙, 최대 힙 구현하기
출처:https://velog.io/@yyj8771/Python-heapq를-이용한-최소-힙-최대-힙
무엇?
- heapq
- 최소 힙, 최대 힙을 만들 때
- 주의할 점은 디폴트에 최소 힙 구현에 맞춰져 있어서, 최대 힙을 만드려면 push할 때
-1
을 곱한 값으로 넣어주고, pop할 때도-1
을 곱한 채로 빼야 정상 작동함! - pop할 때 배열이 비어있으면 인덱스 에러 뜸
heap = []
힙으로 사용할 배열 선언- 메소드
heapq.heappush(배열, 값)
: 최소 힙에 pushheapq.heappop(배열)
: 최소 힙에서 가장 최솟값 popheapq.heappush(배열, -값)
: 최대 힙에 값 push-heapq.heappop(배열)
: 최대 힙에서 가장 최댓값 pop (앞에 마이너스 부호 붙은 거 주의!)
왜?
백준 최대 힙 문제 풀다가, 한땀 한땀 책에 나온 슈도 코드를 보면서 최대 힙 만드는 함수를 구현했는데,
시간 초과로 실패함.
룸메이트님이 보시고 그거 모듈 쓰면 쉽다고 했다. ㅎㅎ
허탈했다. 하지만 그렇게 붙잡고 있던 덕분에 그나마 힙 구조와 친해진 듯.
어떻게?
0을 입력하면 pop하고 정수를 입력하면 push하며 최대 힙 구조를 유지하는 프로그램
import sys
import heapq
N = int(sys.stdin.readline())
heap = []
for _ in range(N):
input = int(sys.stdin.readline())
heap_size = len(heap)
if input == 0:
if heap_size == 0:
print(0)
else:
print(-heapq.heappop(heap))
else: # 정수를 삽입할 때
heapq.heappush(heap, -input)
파이썬에서 PriorityQueue 모듈로 우선순위 큐 구현하기
출처: https://www.daleseo.com/python-priority-queue/
https://johnyejin.tistory.com/72
무엇?
- PriorityQueue
from queue import PriorityQueue
- 가장 작은 숫자의 우선순위를 가진 원소가 나가게 됨(최소 힙 형태)
- 우선순위 큐는 인덱스로 접근 불가능(ex:
que[0]
같은 것 안됨!) - iterable하지 않음. get으로 제일 작은 거부터 빼는 것만 가능하다고 함
- 메소드
que = PriorityQueue(maxsize = 8)
: 최대 크기 설정하고 싶으면 지정que.put((2, "apple"))
:(우선순위, 값)
형태로 튜플로 우선순위와 값을 지정해 넣을 수 있음que.get()
: 가장 작은 숫자를 가진 원소 출력que.qsize()
que.empty()
que.full()
왜?
백준 우선순위 큐 문제에서 사용해보려고 찾음.
그런데 백준에서 해당 모듈 지원 안 한다. ㅠㅠ
하지만 최소 힙 형태이므로 heapq 모듈을 사용하면 된다.
어떻게?
백준 1715번 카드 정렬하기 파이썬 풀이 참고
출처: https://velog.io/@yeseolee/python-자료구조-우선순위-큐Priority-Queue
무엇?
백준 1715번 최소 힙 이용하기
왜?
정답 코드를 보면 하나의 최소 힙만 사용했고,
더한 값을 다시 그 최소 힙에 넣어서 쉽게 계속 최소 값끼리 더할 수 있게 만들었음.
나는 오로지 입력된 카드 더미의 수를 담는데만 최소 힙을 쓰고,
그 외의 횟수 연산을 위해 일반 리스트를 두개나 사용했다.
따라서 별로 효율적이지 못했음. (코드 짜면서도 시간 초과 뜰 거 같았는데 역시 뜸)
또 더한 값도 최소 힙을 이용해야 계속 최소값끼리 더할 수 있게끔 보장되는데,
나는 그렇게 안 했기 때문에 시간 초과 문제를 떠나 예제는 맞아도 정확하지 않음.
어떻게?
▽ 내 코드 중 문제의 부분.
다시 보니 temp, count를 그냥 하나의 int 값을 담는 count 변수만 사용해도 됐겠다.
minheap = []
temp = []
for i in range(2):
pop_out = heapq.heappop(minheap)
temp.append(pop_out)
count = []
count.append(sum(temp))
while len(minheap) != 0:
pop_out = heapq.heappop(minheap)
count.append(sum(count)+pop_out)
print(sum(count))
▽ 수정 후
count = 0
while len(minheap) != 1:
pop_out1 = heapq.heappop(minheap) #최소 값 두 개씩 빼서 더함
pop_out2 = heapq.heappop(minheap)
count += (pop_out1 + pop_out2)
heapq.heappush(minheap, pop_out1 + pop_out2)
print(count)
'크래프톤정글 > TIL & WIL' 카테고리의 다른 글
크래프톤정글 3주차; TIL 2 - 파이썬 BST, 최소 신장 트리 (0) | 2022.11.14 |
---|---|
크래프톤정글 3주차; TIL 1 - 트리와 그래프, 자료 구조의 분류 (0) | 2022.11.14 |
크래프톤정글 2주차; TIL 3 - 힙, 힙 정렬, 우선순위 큐, 파이썬 deque, 파이썬 print 함수 옵션 (0) | 2022.11.08 |
크래프톤정글 2주차; TIL 2 - 백준 곱셈 문제, 괄호의 값 문제 (0) | 2022.11.06 |
크래프톤정글 2주차; TIL 1 - 이진 탐색, 공유기 설치 문제, 함수와 분할정복, 이진 탐색 트리 (0) | 2022.11.06 |