[프로그래머스] 힙 - 더 맵게-Java(자바)
[문제설명]
매운 것을 좋아하는 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인 음식과 2인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.
새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5
가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12] - 스코빌 지수가 3인 음식과 5인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.
새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13
가진 음식의 스코빌 지수 = [13, 9, 10, 12]
모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다.
[나의 풀이]
- 처음에 그냥 List를 썼다가 효율성 문제로 통과 못할뻔했다.
- PriorityQueue라는 자료구조가 있는데 이것을 사용해야 효율성 문제를 통과할 수 있었다고 한다.
import java.util.PriorityQueue;
class Solution {
public int solution(int[] scoville, int K) {
int answer = 0;
PriorityQueue<Integer> heap = new PriorityQueue<>();
// 1. 제공받은 scoville은 배열이므로 priorityqueue에 음식(요소) 넣기
for(int i=0; i<scoville.length; i++){
heap.offer(scoville[i]);
}
while(heap.peek() < K){ // 2. 음식맵기지수가 K보다 작으면 실행.
if(heap.size() < 2) return -1; // 2-1. 비교할거리가 없으면 -1 리턴.
int f1 = heap.poll(); // 3. 맨앞의 요소(0번째) 삭제(poll)하고 fl변수에 반환
int f2 = heap.poll();
// 3. 맨앞의 요소(0이삭제되었으니 한칸씩 앞으로) 삭제(poll)하고 f2변수에 반환
int sco = f1 + (f2 * 2); // 4.반환받은 두 수 스코빌지수 계산.
heap.offer(sco); // 5.priorityQueue에 나온 값 넣기
answer++; // 실행할때마다 answer증가.
}
return answer;
}
}
[PriorityQueue<>]
- 우선순위 큐 클래스
- 우선순위를 먼저 결정하고, 그 우선순위가 높은 엘리먼트가 먼저 나가는 자료구조이다.
- 내부구조가 힙으로 구성되었기 때문에 시간 복잡도가 O(NLogN)
* 선언방법
// [낮은 숫자부터-오름차순]
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
// [높은 숫자부터-내림차순]
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Collections.reverseOrder());
* 다루는 명령어
- .peek( ) : get( )과 같은 기능.
- .poll( ) : remove( )와 같은 기능
- .offer( ) : add( )와 같은 기능
[남의 풀이]
- 간결해서 가져와봤다. return값에 삼항연산자로 표현할수도 있었다.
public int NamEuiGut (int[] scoville, int K) {
PriorityQueue<Integer> pqScov = new PriorityQueue<>();
for (int s: scoville) {
pqScov.add(s);
}
int cnt = 0;
while (pqScov.size() > 1 && pqScov.peek() < K) {
// pq가 1보다 크고, K보다 작아야 실행.
pqScov.add(pqScov.remove() + pqScov.remove() * 2);
cnt++;
}
return pqScov.peek() >= K ? cnt : -1;
}
'코딩테스트[Java]' 카테고리의 다른 글
[프로그래머스] 두 개 뽑아서 더하기-Java(자바) (0) | 2021.03.29 |
---|