일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 10866
- 백준 1712
- 상속
- 테슬라폰
- network
- 계층화
- AWS CLF
- aws 자격증
- 논리구성도
- 네트워크
- 다형성
- 백준 2775
- TCP/IP
- 자바
- modifiers
- 개발바닥
- 자바의 정석
- 파이썬
- 인프콘
- 남궁성
- 데이터 송수신
- 1764
- 프로토콜
- 물리구성도
- 유선LAN
- 인터페이스
- java
- 역캡슐화
- l3 스위치
- 파이썬 1712
- Today
- Total
병훈's Blog
[Python] [백준] 1927번 - 최소 힙 (heapq) 본문
1 초 (추가 시간 없음) (하단 참고) | 128 MB | 51849 | 24108 | 18964 | 48.694% |
문제
널리 잘 알려진 자료구조 중 최소 힙이 있다. 최소 힙을 이용하여 다음과 같은 연산을 지원하는 프로그램을 작성하시오.
- 배열에 자연수 x를 넣는다.
- 배열에서 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다.
프로그램은 처음에 비어있는 배열에서 시작하게 된다.
입력
첫째 줄에 연산의 개수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다. x는 231보다 작은 자연수 또는 0이고, 음의 정수는 입력으로 주어지지 않는다.
출력
입력에서 0이 주어진 횟수만큼 답을 출력한다. 만약 배열이 비어 있는 경우인데 가장 작은 값을 출력하라고 한 경우에는 0을 출력하면 된다.
예제 입력 1 복사
9
0
12345678
1
2
0
0
0
0
32
예제 출력 1 복사
0
1
2
12345678
0
리스트에 자연수를 넣고, 최솟값을 출력한다.
1. 틀린코드
n = int(input())
arr = []
for i in range(n):
num = int(input())
if num == 0:
print(arr.pop() if len(arr) != 0 else 0)
else:
arr.append(num)
arr.sort(reverse=True)
1. append()로 수를 넣고, sort()로 정렬하고, min(list)로 최솟값을 빼면 된다.
==> for문 n번 반복(N) X sort() 사용(NlogN) ==> 시간복잡도 O(N²logN)
==> 시간초과
import bisect
n = int(input())
arr = []
for i in range(n):
num = int(input())
if num == 0:
print(arr.pop(0) if len(arr) != 0 else 0)
else:
arr.insert(bisect.bisect_left(arr, num), num) if arr else arr.append(num)
2. 아니면 bisect를 사용해 정렬된 list에 자신이 들어갈 위치를 찾아서 들어가고, list[0]만 계속 빼면 된다.
==> for문 n번 반복(N) X insert() 사용(N) X bisect사용(logN) ==> 시간복잡도 O(N²logN)
==> 시간초과
from sys import stdin
import heapq
numbers = int(stdin.readline().rstrip())
heap = []
for _ in range(numbers):
num = int(stdin.readline())
if num != 0:
heapq.heappush(heap, num)
else:
print(heapq.heappop(heap) if heapq else 0)
3. 최소힙을 사용하면 된다. 수가 들어갈 때, 최솟값이 항상 root node에 위치하도록 정렬되기 때문이다.
==> for문 n번 반복(N) X ( heappush() 사용(logN) 또는 heappop사용(logN) ) ==> 시간복잡도 O(NlogN)
==> 런타임 에러
2. 맞은 코드
from sys import stdin
import heapq
input = stdin.readline
numbers = int(input())
heap = []
#Min Heap
for _ in range(numbers):
num = int(input())
if num != 0:
heapq.heappush(heap, num) # heap이라는 list에 num을 최소힙 방식으로 삽입한다.
else: # num이 0 이라면
try:
print(heapq.heappop(heap)) # 루트노드의 최솟값을 출력함
except:
# heap이 비어있어서
# 뽑아낼(heapq.heappop 할) 원소가 없다면
print(0) # 0을 출력함
==> for문 n번 반복(N) X ( heappush() 사용(logN) 또는 heappop사용(logN) ) ==> 시간복잡도 O(NlogN)
위와 차이는 try-except문 정도인데
왜 틀리고 왜 맞은걸까...
* heappush는 heap방식으로 삽입한다.
* heappop은 루트노드를 빼내고, heap 형태를 유지한다.
'Algorithm' 카테고리의 다른 글
[Python] [백준] 1260번 - DFS와 BFS (DFS/BFS) (0) | 2022.10.14 |
---|---|
[Python] [백준] 11279번 - 최대 힙 (heapq) (0) | 2022.10.13 |
[Python] [백준] 1764번 - 듣보잡 (set 사용) (1) | 2022.10.13 |
[Python] [백준] 4949번 - 균형잡힌 세상 (stack 사용) (0) | 2022.10.13 |
[Python] [백준] 10816번 - 숫자 카드 2 (여러가지 사용) (0) | 2022.10.11 |