Notion에서 작성한 글이라, 여기 에서 더 깔끔하게 보실 수 있습니다! 😮😊
def findRelativeRanks(self, score: List[int]) -> List[str]:
score = sorted(enumerate(score), key=lambda x: -x[1])
medals = {0:"Gold Medal", 1:"Silver Medal", 2:"Bronze Medal"}
place = [0]*len(score)
for i in range(len(score)):
place[score[i][0]] = medals[i] if i in medals else str(i+1)
return place
enumerate
를 이용하여 인덱스를 마킹해 놓고 점수를 기준으로 정렬시켜서 각 점수가 누구의 점수이며 그 점수를 받은 사람은 몇 등인지의 정보를 만들어 낸다.place
리스트를 만들어 놓고, score
를 순회하며(첫 번째 원소가 1등, …, 끝에 있는 원소가 꼴등) 마킹해놓았던 인덱스를 이용해 place
를 채워나간다.def findRelativeRanks(self, score: List[int]) -> List[str]:
n = len(score)
heap = []
place = [0]*n
medals = {0:"Gold Medal", 1:"Silver Medal", 2:"Bronze Medal"}
for i in range(n):
heappush(heap, (-score[i], i))
for i in range(n):
place[heappop(heap)[1]] = medals[i] if i in medals else str(i+1)
return place
heappush()
한다. 이렇게 최대 힙을 구성하고 나면, heappop()
을 이용하여 1등부터 차례대로 인덱스를 빼내어 순위 정보를 갱신해 주는 식이다.def findRelativeRanks(self, score: List[int]) -> List[str]:
n = len(score)
place = [0]*n
medals = {0:"Gold Medal", 1:"Silver Medal", 2:"Bronze Medal"}
heap = [(-s, i) for i, s in enumerate(score)]
heapify(heap)
for i in range(n):
place[heappop(heap)[1]] = medals[i] if i in medals else str(i+1)
return place
heappush()
하여 힙을 구성하는 방식과, heapify()
로 한 번에 힙을 구성하는 시간에는 차이가 있다.heapify()
는 에 리스트를 힙으로 만들어 준다. 이를 이용하기 위해, 먼저 enumerate
를 이용하여 에 점수와 인덱스를 묶어 놓고, heapify()
를 이용하여 에 최대 힙을 구성한다.from heapq import *
def solution(scoville, K):
heapify(scoville)
cnt = 0
while scoville[0] < K and len(scoville) >= 2:
heappush(scoville, heappop(scoville)+heappop(scoville)*2)
cnt += 1
if scoville[0] < K: return -1
else: return cnt
from heapq import *
from collections import deque
def mix(f, h, q):
if h[0] < q[0]: q.append(f + 2*heappop(h))
else: q.append(f + 2*q.popleft())
def solution(scoville, K):
heapify(scoville)
queue = deque([])
cnt = 0
while len(scoville)+len(queue) > 1:
if min(scoville[0] if scoville else queue[0], queue[0] if queue else scoville[0]) >= K:
return cnt
if scoville and queue:
if scoville[0] < queue[0]:
first = heappop(scoville)
if scoville: mix(first, scoville, queue)
else: queue.append(first + 2*queue.popleft())
else:
first = queue.popleft()
if queue: mix(first, scoville, queue)
else: queue.append(first + 2*heappop(scoville))
elif scoville:
queue.append(heappop(scoville) + 2*heappop(scoville))
else:
queue.append(queue.popleft() + 2*queue.popleft())
cnt += 1
if min(scoville[0] if scoville else queue[0], queue[0] if queue else scoville[0]) >= K:
return cnt
else: return -1
heappush()
하는 데에 걸리던 대신 queue
에 append()
함으로써 Amortized 로 줄였다.queue[0]
)이 한 번도 섞이지 않은 최소 스코빌 지수(scoville[0]
)보다 작을 때), 기존에 heappop
하는 데에 걸리던 대신 queue
에서 popleft()
함으로써 로 줄였다.popleft()
로 시간복잡도상의 이득을 못 보는 경우라고 볼 수 있다. 다만 이 경우에도 heappush()
대신 append()
을 이용함으로써 대신 Amortized 로 줄어든다. ∴ def solution(scoville, K):
scv = deque(sorted(scoville))
mixed = deque()
cnt = 0
while (scv and scv[0]<K) or (mixed and mixed[0]<K):
if len(scv)+len(mixed) < 2:
return -1
item = [0]*2
for i in range(2):
if scv and mixed:
if scv[0] < mixed[0]:
item[i] = scv.popleft()
else:
item[i] = mixed.popleft()
elif scv:
item[i] = scv.popleft()
else:
item[i] = mixed.popleft()
mixed.append(item[0] + 2*item[1])
cnt += 1
return cnt
scoville
을 정렬시켜서 queue로 바꾼다. 이를 통해 얻는 효과는, Solution 2.에서처럼 heappop()
을 통해 매번 으로 heap을 유지시켜서 최솟값을 에 찾을 수 있도록 할 필요가 없다.popleft()
만 한다면, 정렬된 상태가 유지되기때문에 여전히 최솟값을 에 찾을 수 있게 된다.from heapq import *
heap = []
for _ in range(int(input())):
n = int(input())
if n: heappush(heap, n)
else: print(heappop(heap) if heap else 0)