[프로그래머스 - 힙] 더 맵게

    🔍문제

    매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.

    섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)

    Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다.

    Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.

    제한 사항

    • scoville의 길이는 2 이상 1,000,000 이하입니다.
    • K는 0 이상 1,000,000,000 이하입니다.
    • scoville의 원소는 각각 0 이상 1,000,000 이하입니다.
    • 모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return 합니다.

    입출력 예

    scoville K return

    [1, 2, 3, 9, 10, 12] 7 2

    입출력 예 설명

    1. 스코빌 지수가 1인 음식과 2인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12]
    2. 새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5
    3. 스코빌 지수가 3인 음식과 5인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.가진 음식의 스코빌 지수 = [13, 9, 10, 12]
    4. 새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13

    모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다.

     


    💡 풀이 

    1. 리스트를 힙으로 만든다.
    2. 스코빌 계산을 위해, heappop()형식으로 가장 맵지 않은 음식의 스코빌 지수를 얻는다.
    3. 스코빌이 K 만큼 나오고, 스코빌의 길이가 1이라면 -1을 return한다.

     💣 문제 발생:  배열 요소가 없음

    import heapq
    
    def solution(scoville, K):
        heapq.heapify(scoville) 
        mix_count = 0
        
        while scoville[0] < K: 
            first = heapq.heappop(scoville)
            second = heapq.heappop(scoville)
            mix = first + (second * 2)
            heapq.heappush(scoville, mix)
            mix_count += 1
            if len(scoville) < 2:
                return -1
        return mix_count

    AI 코드 피드백
    사용자의 코드에서 무한 루프에 빠질 위험이 있는 부분이 있습니다. 만약 scoville[0]이 K보다 작아 섞어야 하지만, `len(scoville) < 2`인 조건을 체크하는 부분이 현재 위치에서는 섞는 과정 이후에 오기 때문에, 리스트의 길이가 2 미만일 때 `heapq.heappop(scoville)`을 두 번 호출하는 경우 IndexError가 발생할 수 있습니다. 즉, 첫 번째 요소를 꺼낸 후 배열의 크기가 1 이하면, 두 번째 요소를 꺼내려고 할 때 배열에 요소가 없어 에러가 발생하거나 잘못된 로직이 될 수 있습니다. 따라서, 배열의 길이를 확인하는 조건문의 위치를 섞기 전에 체크해야 합니다. 배열의 크기가 2 미만일 때 -1을 반환하는 로직의 위치를 조정해 볼 필요가 있습니다. 이렇게 배열의 길이를 먼저 확인하면, 필요한 연산을 수행하기 전에 더 이상 진행할 수 없는 상황을 사전에 방지할 수 있습니다.

    스코빌 힙의 길이가 2보다 작다면 더 이상 진행할 필요가 없다.

    나는  if문을 하단에 배치하여 heap의 두 번째로 작은 값을 호출할 때 에러가 발생하였다. 

     

    import heapq
    def solution(scoville, K):
        heapq.heapify(scoville) 
        mix_count = 0
        
        while scoville[0] < K: 
            if len(scoville) < 2:
                return -1
            first = heapq.heappop(scoville)
            second = heapq.heappop(scoville)
            mix = first + (second * 2)
            heapq.heappush(scoville, mix)
            mix_count += 1
        return mix_count

     

    나는  if문을 상단에 배치하여 애초에 실행될 필요가 없다면 return -1 이 되도록 수정하였다. 

     

     

    💡 풀이 2

    풀이 1를 간결하게 코드를 작성하기 위해, 불필요한 변수는 선언하지 않는 방식으로 생각하였다. 

    힙은 인덱스 0이 최솟값이라고 해서, 인덱스 1에 두 번째, 인덱스 2에 세 번째로 작은 원소가 있는 것이 아니다.

    두 번째로 작은 원소를 얻기 위해서는 heappop()을 사용하여 최솟값을 삭제 후, heap[0]으로 접근하는 방식을 사용하거나, 인덱스 1과 인덱스 2를 비교하는 방식을 사용한다. 

    import heapq
    def solution(scoville, K):
        mix_count = 0
        heapq.heapify(scoville)
        
        while scoville[0] < K:
            mix = heapq.heappop(scoville) + (heapq.heappop(scoville)*2)
            heapq.heappush(scoville, mix)
            mix_count += 1
            if scoville[0] > K and len(scoville) < 2:
                return -1
        return mix_count

     

     

    댓글