이중 우선순위 큐는 다음 연산을 할 수 있는 자료구조를 말합니다.
| 명령어 | 수신 탑(높이) |
|---|---|
| I 숫자 | 큐에 주어진 숫자를 삽입합니다. |
| D 1 | 큐에서 최댓값을 삭제합니다. |
| D -1 | 큐에서 최솟값을 삭제합니다. |
이중 우선순위 큐가 할 연산 operations가 매개변수로 주어질 때, 모든 연산을 처리한 후 큐가 비어있으면 [0,0] 비어있지 않으면 [최댓값, 최솟값]을 return 하도록 solution 함수를 구현해주세요.
| operations | return |
|---|---|
| ["I 16", "I -5643", "D -1", "D 1", "D 1", "I 123", "D -1"] | [0,0] |
| ["I -45", "I 653", "D 1", "I -642", "I 45", "I 97", "D 1", "D -1", "I 333"] | [333, -45] |
입출력 예 #1
입출력 예 #2
풀이
처음에는 heap을 두 개 사용해서 최소 힙과 최대 힙을 구성하려했는데 특정 값을 pop했을 때 두 힙을 동기화 시켜주는 부분이 까다로울 것 같다는 생각이 들었다
따라서 최대 힙을 만들어 줄 때 -1을 곱해주는 방식에 기반해서 하나의 힙으로 구현했다
최소값을 삭제하는 명령어 일 때는 별 다른 처리를 해주지 않고 heap에서 pop을 하면 된다
다만 최대값을 삭제해야하는 경우 map 함수를 사용해서 리스트의 모든 원소들에 -1을 곱해주고 heapify와 heappop을 수행했다
이후에는 다시 리스트의 모든 원소들에 -1을 곱해 원 상태로 복귀시키고 heapify를 수행한다
사실 내 풀이는 의 시간복잡도를 갖기 때문에 통과하기 어려운 코드가 맞는데, 이상하게도 정답이 되었다
코드
import heapq
def solution(operations):
arr = []
for command in operations:
if command[0] == "I":
heapq.heappush(arr, int(command[2:]))
# print("push %d result : "%(int(command[2:])),arr)
else:
if arr:
if command[2:] == "1":
arr = list(map(lambda x:-x, arr))
heapq.heapify(arr)
num = heapq.heappop(arr)
arr = list(map(lambda x:-x, arr))
heapq.heapify(arr)
# print("pop max %d result : "%(-num),arr)
else:
num = heapq.heappop(arr)
# print("pop min %d result : "%(num),arr)
if arr:
return [max(arr), min(arr)]
else:
return [0,0]
좋은 코드
나와 비슷하게 하나의 heap을 가지고 최대와 최소를 구하고 시간복잡도도 괜찮은 코드가 있었다
최대값을 구할 때가 문제가 되므로, 의 시간복잡도가 생기는 나의 방법을 사용하기보다 오름차순으로 정렬된 arr에서 맨 마지막 원소를 pop하면 된다
heap은 최소값을 제외한 나머지 요소들의 순서를 건드리지 않는다고 한다 따라서 insert 한 후에 정렬해주면 된다
import heapq
def solution(operations):
q = []
for op in operations:
if op == "D 1":
if q: q.pop()
elif op == "D -1":
if q: heapq.heappop(q)
else:
num = int(op.split(" ")[-1])
heapq.heappush(q, num)
q.sort()
if q:
return [q[-1], q[0]]
else:
return [0, 0]