Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
Tags
- OpenAI
- 코딩테스트
- frontend
- retriever
- backend
- 스택/큐
- React
- InfluxDB
- MCP
- 파이썬
- 프로그래머스
- chroma
- javascript
- queue
- VectoreStore
- rag
- DP
- dfs
- LLM
- python
- Two Pointer
- heapq
- AI
- modbus
- javascirpt
- BFS
- Algorithm
- typescript
- 알고리즘
- 완전탐색
Archives
- Today
- Total
DM Log
[Heap] 이중우선순위큐 - Python 본문
문제 링크 - https://school.programmers.co.kr/learn/courses/30/lessons/42628?language
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
[문제 간단 요약]
- 큐에 숫자를 삽입하거나 최댓값/최솟값을 삭제하는 연산이 주어진다.
- 모든 연산을 수행한 후, 큐가 비어 있지 않다면 [최댓값, 최솟값]을 반환하고, 비어 있으면 [0, 0]을 반환한다.
[문제 해결 방안]
✅ Heap
- 파이썬의 heapq는 최소 힙만 지원하므로,
- 최솟값 관리: 일반 힙(li)
- 최댓값 관리: 음수 변환하여 힙(revert_li)
- 삽입 시 두 힙에 모두 넣어 동기화
- 삭제 시 조건에 맞게 하나에서 heappop 후, 다른 힙에서도 해당 원소를 remove로 제거
- 마지막에 힙이 비었는지 여부를 확인 후 결과 반환
[문제 해결 코드 - python]
import heapq
def solution(operations):
li = []
revert_li = []
for operation in operations:
if operation[0] == 'I':
heapq.heappush(li, int(operation[2:]))
heapq.heappush(revert_li, -int(operation[2:]))
elif len(li) != 0 and operation[0] == 'D':
if operation[1:] == ' -1':
chk_num = heapq.heappop(li)
revert_li.remove(-chk_num)
elif operation[1:] == ' 1':
chk_num = heapq.heappop(revert_li)
li.remove(-chk_num)
if len(li) == 0:
answer = [0,0]
elif len(li) == 1:
num = heapq.heappop(li)
answer = [num,num]
else:
answer = [-heapq.heappop(revert_li), heapq.heappop(li)]
return answer
[코드 개선점]
- list.remove() 비효율성
- remove()는 O(n) → 연산 횟수가 많아질수록 성능 저하
- 개선: lazy deletion (삭제된 원소 표시만 하고 실제 pop 시 제거)
- 중복 원소 처리
- 같은 값이 여러 번 들어간 경우, remove()는 첫 번째 원소만 제거
- 다른 힙에 동일 값이 여러 개 들어 있으면 싱크가 깨질 수 있음
- 코드 가독성
- "I" 연산 처리 시 int(operation[2:]) 중복 → 한 번만 파싱
- "D -1", "D 1" 비교 시 문자열 slicing 대신 split() 활용 가능
- 최종 결과 반환 시 부작용
- heapq.heappop()을 사용해 실제 힙을 꺼내므로, 결과를 반환한 뒤 원본 상태가 사라짐
- 문제 풀이에선 상관없지만, 함수 호출 후 힙을 유지해야 한다면 부적절
[문제 해결 코드 - python]
import heapq
def solution(operations):
min_h, max_h = [], []
exist = {} # lazy deletion 관리용 딕셔너리
def clean(heap, is_max=False):
# 유효하지 않은 값 제거
while heap and exist.get((val := (-heap[0] if is_max else heap[0])), 0) == 0:
heapq.heappop(heap)
for op in operations:
if op[0] == 'I':
num = int(op[2:])
heapq.heappush(min_h, num)
heapq.heappush(max_h, -num)
exist[num] = exist.get(num, 0) + 1
elif op == "D -1":
clean(min_h)
if min_h:
val = heapq.heappop(min_h)
exist[val] -= 1
elif op == "D 1":
clean(max_h, True)
if max_h:
val = -heapq.heappop(max_h)
exist[val] -= 1
clean(min_h)
clean(max_h, True)
if not min_h or not max_h:
return [0, 0]
return [-max_h[0], min_h[0]]
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[DFS/BFS] 단어 변환 - Python / JavaScript (0) | 2025.09.14 |
---|---|
[Heap] 야근 지수 - Python / JavaScript (0) | 2025.09.13 |
[DP] 정수 삼각형 - Python / JavaScript (0) | 2025.09.07 |
[DFS] 네트워크 - Python / JavaScript (0) | 2025.09.06 |
[Greedy] 마법의 엘리베이터 - Python / JavaScript (0) | 2025.08.24 |