문제

매운 것을 좋아하는 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 합니다.

나의 코드

import java.util.*;

public class MoreSpicy {
	
	 public static int solution(int[] scoville, int K) {
	        int answer = 0;
	        Heap h = new Heap();
	        for(int m : scoville) {
	        	h.insert(m);
	        }
	        
	        while(true) {
	        	int com = h.delete();
	        	if(h.heapSize()==1 && com<K) {
	        		return -1;
	        	}
	        	if(com < K) {	
	        		answer++;
	        		h.insert(com+(h.delete()*2));
	        	}else {
	        		break;
	        	}
	        }
	        return answer;
	    }
}

class Heap {	//MinimumHeap 
    List<Integer> heap;

    public Heap() {
        heap = new ArrayList<Integer>();
        heap.add(0);
    }
    public int heapSize() {
    	return heap.size();
    }
    public void insert(int n) {
        heap.add(n);
        int p = heap.size() - 1;
        while (p < 1 || heap.get(p / 2) > heap.get(p)) {
            // 부모노드와 자식 노드의 값 교환
            int tmp = heap.get(p / 2);
            heap.set(p / 2, heap.get(p));
            heap.set(p, tmp);
            p = p / 2;
        }
    }
    public int delete() {
        if (heap.size() <= 1)
            return 0;
        int deleteItem = heap.get(1); // 삭제할 노드 = 루트노드

        heap.set(1, heap.get(heap.size() - 1));
        heap.remove(heap.size() - 1);

        int pos = 1;
        while ((pos * 2) < heap.size()) {
            int min = heap.get(pos * 2);
            int minPos = pos * 2;

            if (((pos * 2 + 1) < heap.size()) && min > heap.get(pos * 2 + 1)) {
                min = heap.get(pos * 2 + 1);
                minPos = pos * 2 + 1;
            }
            if (heap.get(pos) < min)
                break;
            // 부모노드 자식노드 교환
            int tmp = heap.get(pos);
            heap.set(pos, heap.get(minPos));
            heap.set(minPos, tmp);
            pos = minPos;
        }
        return deleteItem;
    }
}

나의 풀이

1. 먼저 최소 힙을 구현한다.

2. 구현한 Heap의 메서드는 총 3개 ( insert, delete, heapSize )

  1. 생성자 : Heap은 트리구조를 구성하기 위해 첫 번째 값에 인덱스 0에 먼저 값을 채워 넣어 인덱스가 1부터 시작할 수 있게 한다.
  2. insert : 리스트에 insert인자로 들어온 값을 추가한다. while문을 통해 부모노드보다 작게 되면 부모 노드와 자식 노드를 교환
  3. delete : 사이즈가 1이하면 리스트에 값이 없다는 것이기 때문에 return 0 , 아니라면 삭제한 값 리턴,  최솟값을 삭제하며 노드의 구성을     재배치
  4. heapSize : 리스트의 사이즈를 리턴한다.

3. for문을 통해 주어진 맵기의 배열을 heap에 추가시킨다.

4. 먼저 무한 루프를 돌린다.

5. 힙의 첫번째 값을 삭제하며 int com에 저장한다.

6. 힙의 사이즈가 1(리스트가 비었음)이고, 첫 번째 값이 원하는 맵기보다 작다면 -1 return

7. 만약 삭제한 값이 원하는 맵기보다 작으면 한번 섞으면서 answer++

8. 그게 아니라면(삭제한 값이 원하는 맵기보다 크면) break;

9. answer를 리턴한다.

'코딩테스트 풀이 > 프로그래머스' 카테고리의 다른 글

힙 - 디스크 컨트롤러 [JAVA]  (0) 2020.06.01
힙 - 라면공장 [JAVA]  (1) 2020.05.30
스택/큐 - 주식가격 [JAVA]  (0) 2020.05.27
스택/큐 - 쇠막대기 [JAVA]  (0) 2020.05.27
스택/큐 - 프린터 [JAVA]  (0) 2020.05.26

+ Recent posts