더 맵게 문제 풀이에 대한 글입니다. 문제 설명은 다음의 링크를 확인해주시기 바랍니다. 문제 설명
코딩테스트 연습 - 더 맵게
매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같
programmers.co.kr
더 맵게 문제는 모든 음식의 스코빌 지수를 K 이상으로 만드는데 몇 번의 계산을 했는지를 구하는 문제입니다. 여기서 계산은 다음과 같이 진행됩니다.
섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
위의 계산을 수행하기 위해서는 주어진 스코빌 배열에서 가장 작은 스코빌 지수, 두 번째로 작은 스코빌 지수를 계산이 완료될 때까지 가져와야 합니다. 계산을 다시 시작할 때마다 배열을 정렬시켜 배열[0], 배열[1]의 값을 가져오는 방법을 선택할 수도 있지만 이 방법은 정렬의 시간 복잡도 O(nlogn) 최악의 경우 n번의 반복이 합쳐 저 O(n^2 logn)의 시간 복잡도가 나올 수 있습니다. 따라서 답은 구할 수 있겠지만 효율성 테스트에서 시간 초과가 나옵니다.
이 문제를 해결하기 위해서는 힙을 사용해야 합니다. 힙의 성질은 다음과 같습니다. 기준은 최소힙입니다.
- 부모 노드의 값이 자식 노드의 값보다 항상 작다.
- 완전 이진트리의 성질을 만족합니다.
파이썬에서 제공하는 heapq 모듈의 주요 기능 시간 복잡도는 다음과 같습니다.
- 주어진 배열을 힙으로 변환하는 heapify()는 O(n)
- 힙에 원소를 추가하는 heappush()는 O(logn)
- 힙의 원소를 제거하는 heappop()은 O(logn)
따라서 힙을 사용하면 O(n)의 시간 복잡도로 문제를 해결할 수 있습니다.
다음은 힙을 사용하여 문제를 해결하는 순서입니다.
- scoville 배열을 힙으로 변환한다.
- 가장 작은 값이 K보다 큰지 확인한다.
- 2번을 만족하면 answer를 반환한다.
- scoville 배열의 길이가 2보다 큰지 확인한다.
- 4번을 만족하면 정답이 존재하지 않으므로 -1을 반환한다.
- 첫 번째로 작은 scoville과 두 번째로 작은 scoville을 힙의 성질을 이용하여 꺼낸다.
- 문제에서 제시한 식에 맞게 스코빌을 계산한 원소를 scoville에 힙의 성질에 맞게 넣어준다.
- 2를 반복한다.
위의 해결 순서에서 2번과 4번은 정답과 실패를 판단하는 조건입니다.
2번의 경우 가장 작은 값이 K보다 크다면 scoville 배열의 다른 모든 값이 K보다 크다고 할 수 있기 때문에 answer를 반환합니다. 4번의 경우 배열의 길이가 2보다 작다면 더 이상 새로운 스코빌을 계산할 수 없기 때문에 정답이 없다는 의미로 -1을 반환합니다.
해결 순서를 바탕으로 코드를 작성하면 다음과 같습니다.
import heapq
def calcShakeScoville(first, second):
return first + (second * 2)
def solution(scoville, K):
answer = 0
heapq.heapify(scoville)
while scoville[0] < K:
if len(scoville) < 2:
return -1
else:
first = heapq.heappop(scoville)
second = heapq.heappop(scoville)
heapq.heappush(scoville, calcShakeScoville(first, second))
answer += 1
return answer
배열에서 힙의 성질은 정렬시키는 것으로도 만족시킬 수 있습니다. 따라서 heapq.heapify(scoville) 부분을 scoville.sort()로 변환하여도 문제를 해결할 수 있습니다. 힙을 사용해야 한다는 것만 안다면 어렵지 않게 문제를 해결할 수 있습니다.
'취업을 준비하며 정리하는 컴퓨터 지식 > Problem Solving' 카테고리의 다른 글
[Problem Solving] 프로그래머스 42576 완주하지 못한 선수 (0) | 2022.01.13 |
---|---|
[Problem Solving] 프로그래머스 67257 수식 최대화 (0) | 2022.01.12 |
[Problem Solving] 백준 4963 섬의 개수 (0) | 2022.01.10 |
[Problem Solving] 백준 7569번 토마토 문제풀이 (0) | 2021.09.29 |
[Problem Solving] 백준 3020번 개똥벌레 파이썬 (0) | 2021.09.25 |