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