https://www.acmicpc.net/problem/1655
1655번: 가운데를 말해요
첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. 정수는 -1
www.acmicpc.net
이 문제는 우선순위큐 알고리즘으로 해결해야 하는 문제이다.
처음 문제를 접했을때 큐를 사용해야겠다는 생각은 했으나, 중앙값을 리턴하는 메소드를 구현할때 sorted()를 이용하였다.
파이썬에서 sorted()를 사용하면 대다수의 경우에서 시간초과가 계속 나타나는데 역시나 시간초과로 해결하지 못하였다.
아래 코드는 내가 처음 시도했던 코드이다.
import sys
class myQueue(object):
def __init__(self):
self.queue = []
def enqueue(self, n):
self.queue.append(n)
pass
def sort(self):
self.queue = sorted(self.queue)
def median(self):
length = len(self.queue)
if length % 2 == 0:
return self.queue[int(length/2)-1]
return self.queue[int(length-1)//2]
N = int(sys.stdin.readline())
q = myQueue()
for _ in range(N):
q.enqueue(int(sys.stdin.readline()))
q.sort()
print(q.median())
참고로 input() 대신 sys.stdin.readline()을 사용하면 시간초과를 어느정도 예방할 수 있다고 한다.
아무튼, 그렇다면 이 문제에서 중앙값은 sorted()를 사용하지 않고 어떻게 해결할 수 있을까?
이때 필요한 것이 바로 우선순위 큐(Priority Queue)다.
우선순위 큐는 모든 원소에 우선순위가 있고, 이 우선순위가 높은 원소부터 제거하는 자료구조를 의미한다.
위 알고리즘을 코드로 구현하면 아래와 같다.
# import sys/
import heapq
if __name__ == "__main__":
n = int(input())
max_h, min_h = [], []
# max_h[0][1]값을 기준으로 큰 값은 min_h, 같거나 작은 값은 max_h에 삽입
for _ in range(n):
num = int(input())
if len(max_h) == len(min_h):
heapq.heappush(max_h, (-num, num))
else:
heapq.heappush(min_h, (num, num))
if len(max_h) >= 1 and len(min_h) >= 1 and max_h[0][1] > min_h[0][1]:
max_value = heapq.heappop(max_h)[1]
min_value = heapq.heappop(min_h)[1]
heapq.heappush(max_h, (-min_value, min_value))
heapq.heappush(min_h, (max_value, max_value))
print('num is',num)
print(max_h)
print(min_h)
print(max_h[0][1])
참고로 파이썬의 heapq는 기본적으로 최소힙이기 때문에 최대힙(left)에 삽입해 줄때는, -를 붙여서 -num으로 넣어준다.
'Coding > 알고리즘 오답' 카테고리의 다른 글
(그리디) 백준 20365번 _ 블로그2 [Python] (0) | 2022.10.05 |
---|---|
(그리디) 이것이 코딩테스트다 11장 Q4 _ 만들 수 없는 금액 [Python] (0) | 2022.09.23 |
(DP) 백준 12865번 _ 평범한 배낭 [Python] (0) | 2022.05.25 |
(그리디) 백준 1543번 _ 문서검색 (+ Python 3 와 PyPy3는 무엇이 다를까) (0) | 2022.02.05 |
(그리디) 백준 21758번 _ 꿀 따기 [Python] (1) | 2022.02.02 |
댓글