매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.
섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다.
Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.
| scoville | K | return |
|---|---|---|
| [1, 2, 3, 9, 10, 12] | 7 | 2 |
새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5
가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12]
새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13
가진 음식의 스코빌 지수 = [13, 9, 10, 12]
풀이
최소를 구해야하는 문제인데 리스트의 길이가 최대 1,000,000 이기 때문에 시간 복잡도에 유의해서 풀어야한다
문제 자체는 어렵지 않았는데 이 부분과 heap이 비어있는지 체크하는 부분에서 시간을 생각보다 소요했다
우선은 스코빌 리스트를 heap으로 만들어줘야하기 때문에 heapify를 해줘야한다 오랜만에 heapq를 쓰려니까 이 부분을 까먹었었다
난 heapify안하고 heappop이나 heappush쓰면 그냥 내부적으로 해주는줄 ,,
최대로 탐색할 수 있는 횟수가 스코빌 리스트의 길이이기 때문에 while문 보다는 for문으로 루프를 돌고 for문 내에서 함수를 리턴하지 못하면 -1을 리턴하도록 했다
우선 최소힙의 특성상 리스트의 최소값이 K보다 크면 리스트 내의 모든 원소가 K보다 큰 것이기 때문에 0번째 인덱스 값을 먼저 확인하도록했다
여기에서 heappop을 사용해서 확인하면 어쨌거나 이므로 조금이라도 시간을 줄이기 위해 heappop을 안썼다
그리고 리스트에 남아있는 원소가 없으면 곧바로 -1을 리턴해야하고 원소가 있다면 1개가 남아있는지 2개가 남아있는지를 체크해야한다
처음부터 2개 이상으로 조건을 걸어버리면 원소가 1개인 경우는 체크할 수 없기 때문에 오답이 발생한다
import heapq
def solution(scoville, K):
answer = 0
heapq.heapify(scoville)
n = len(scoville)
for _ in range(n):
if len(scoville) >= 1:
first = scoville[0]
if first >= K:
return answer
first = heapq.heappop(scoville)
if len(scoville) >= 1:
second = heapq.heappop(scoville)
new = first + (second*2)
answer += 1
heapq.heappush(scoville, new)
return -1