삘 받아서 한 문제 더 풀어보았습니다.
약 30분 정도 소요되었습니다. 자료구조에서 들었던 min_heap을 priority_queue라는 STL을 통해 아주 쉽게 구현할 수 있다는 것을 알 수 있었습니다.
목차
0. 문제 설명
매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.
섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다.
Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.
0.0. 제한 사항
- scoville의 길이는 2 이상 1,000,000 이하입니다.
- K는 0 이상 1,000,000,000 이하입니다.
- scoville의 원소는 각각 0 이상 1,000,000 이하입니다.
- 모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return 합니다.
0.1. 입출력 예
scoville | K | return |
[1, 2, 3, 9, 10, 12] | 7 | 2 |
0.2. 입출력 예 설명
-
스코빌 지수가 1인 음식과 2인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.
새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5
가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12] -
스코빌 지수가 3인 음식과 5인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다.
새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13
가진 음식의 스코빌 지수 = [13, 9, 10, 12]
모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다.
1. 풀이 과정
priority queue는 기본적으로 max_heap 구조를 가지고 있습니다.(heap의 맨 꼭대기에 가장 큰 값이 오는 구조)
이걸 min_heap 형태로 바꿔주기 위해서는 greater<int>인자를 세 번째 파라미터로 받아주면 됩니다.
이것만 만들 수 있으면 pop()을 통해 가장 작은 2개를 뽑아서 계산을 해준 후에 다시 넣어주는 것을 반복하면 됩니다.
계산을 몇 번 했는지가 answer이기 때문에 while문 안에 계산을 할 때마다 answer을 1씩 증가시켜줘야 합니다.
그렇게 반복하다가 가장 작은 수가 K를 넘으면 answer를 return하면 되고, 만약 하나가 남아서 더이상 계산이 불가능하다면 그 값을 입력받은 K와 비교하고, K보다 작으면 -1을 return해주면 되는 것이죠.
2. 소스 코드
2.0. 정답인 소스코드
#include <string>
#include <vector>
#include <queue>
using namespace std;
int solution(vector<int> scoville, int K) {
int answer = 0;
priority_queue<int, vector<int>, greater<int>> pq;
int size = scoville.size();
for (int i = 0; i < size; ++i)
pq.push(scoville[i]);
if(pq.top() > K) // 애초부터 min_heap이 K를 넘으면 그대로 0 return
return answer;
while (pq.size() != 1 && pq.top() < K){
int f = pq.top();
pq.pop();
int s = pq.top();
pq.pop();
int cal = f+s*2;
pq.push(cal);
++answer;
}
if (pq.size() == 1 && pq.top() < K)
answer = -1;
return answer;
}
2.1. <부록> 사소한 실수..
마지막 if문에서 size 대신 top을 넣어버렸더니 오류가 발생합니다.
-1인 경우를 제대로 체크하지 못하게 되는데 신기하게 효율성 테스트는 다 통과했네요 ㅋㅋㅋㅋ
#include <string>
#include <vector>
#include <queue>
using namespace std;
int solution(vector<int> scoville, int K) {
int answer = 0;
priority_queue<int, vector<int>, greater<int>> pq;
int size = scoville.size();
for (int i = 0; i < size; ++i)
pq.push(scoville[i]);
if(pq.top() > K) // 애초부터 min_heap이 K를 넘으면 그대로 0 return
return answer;
while (pq.size() != 1 && pq.top() < K){
int f = pq.top();
pq.pop();
int s = pq.top();
pq.pop();
int cal = f+s*2;
pq.push(cal);
++answer;
}
if (pq.top() == 1 && pq.top() < K)
answer = -1;
return answer;
}
3. 후기
priority queue를 처음 사용해봤습니다. 이런 것도 쓸 수 있게 되었다니 참 신기합니다! 앞으로 문제들이 많은데 힙 문제에서는 대부분 priority queue를 사용하겠죠? 재미있을 것 같아서 굉장히 기대됩니다 ^^
출처 : 프로그래머스 코딩테스트 연습, programmers.co.kr/learn/courses/30/lessons/42626
최근댓글