문제 풀이 날짜: 2023.05.03
포스트 작성일: 2023.05.06
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
프로그래머스 코딩테스트 고득점Kit 해시 편 : 베스트앨범 (Lv.3) (문제 링크)
키워드
해시맵, 우선순위 큐
풀이 접근법
- 주어진 조건에 부합하는 노래를 ‘두 곡’만 선정하는데, 만약 조건에 부합하는 것이 오직 한 곡만 존재한다면 한 곡만 수록해야 한다. 조건은 다음과 같다.
- 속한 노래가 많이 재생된 장르를 먼저 수록
- 각 노래별로 총 재생수를 집계하고, 해당 장르의 곡 목록을 탐색한다 ⇒ 정렬 필요
- 장르 내에서 많이 재생된 노래를 먼저 수록
- 그 장르 내에서 가장 재생수가 높은 노래 탐색 ⇒ 정렬 필요
- 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록
- 별도의
Comparator
를 이용한 정렬 기준이 필요하다.
- 별도의
- 장르별 재생수를 집계한 다음에 수록은 어떻게 할까?
- 우선순위 큐에 모든 장르를 넣고, 재생수가 높은 장르를 하나씩 뽑는다. (poll) ⇒
Entry
자료구조 필요 - 해당 장르의 노래들로
Entry<장르, 재생수>
리스트를 만들어 사전순의 반대로 정렬한다. - 앨범 등록을 마친 장르는 자연히 우선순위 큐에서 삭제된 상태이다.
- 큐에 더 이상 들어있는 것이 없다면 종료한다.
- 우선순위 큐에 모든 장르를 넣고, 재생수가 높은 장르를 하나씩 뽑는다. (poll) ⇒
코드
import java.util.*;
class Solution {
public int[] solution(String[] genres, int[] plays) {
int[] answer = {};
HashMap<String, Integer> map = new HashMap<>();
//장르별 총 재생횟수 집계
for(int i = 0; i < genres.length; i++) {
String genre = genres[i];
int play = plays[i];
map.put(genre, map.getOrDefault(genre, 0) + play);
}
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(
(o1, o2) -> Integer.compare(o2.getValue(), o1.getValue())); //내림차순
for(Map.Entry<String, Integer> entry : map.entrySet()) {
pq.add(entry);
}
ArrayList<Integer> result = new ArrayList<>();
//pq에서 재생수가 높은 장르 순으로 뽑으며 앨범에 수록한다.
while(!pq.isEmpty()) {
Map.Entry<String, Integer> entry = pq.poll();
String genre = entry.getKey();
//poll()로 뽑은 장르의 노래들만 모은다.
ArrayList<int[]> list = new ArrayList<>();
for(int i = 0; i < genres.length; i++) {
if(genre.equals(genres[i])) {
int[] a = {i, plays[i]};
list.add(a);
}
}
Collections.sort(list, (o1, o2) -> (Integer.compare(o2[1], o1[1])));
int avaliableSize = 0;
if(list.size() >= 2) {
avaliableSize = 2;
}
else if (list.size() == 1) {
avaliableSize = 1;
}
for(int i = 0; i < avaliableSize; i++) {
int num = (list.get(i))[0];
result.add(num);
}
}
answer = new int[result.size()];
for(int i = 0; i < result.size(); i++) {
answer[i] = result.get(i);
}
return answer;
}
}
해시 문제집에 있었지만 해시 그 자체보다는 여러 자료구조를 알아야 풀기 쉬운 문제인 것 같다. 시간을 정해놓고 풀었기 때문에 급하게 마무리했으나, 개인적으로 코드를 더 깔끔하게 짰으면 좋았을 텐데 하는 아쉬움이 있다. Stream을 사용하면 몇몇 코드를 깔끔하게 다듬을 수 있을 듯하다.
git 링크
https://github.com/jinju9553/23-CodingTest/blob/main/week7/day1/BestAlbum.java
'Study > Problem Solving' 카테고리의 다른 글
[백준 / Java] 11659번: 구간 합 구하기 4 (실버3) (0) | 2023.05.18 |
---|---|
[백준 / Java] 13305번: 주유소 (실버3) (0) | 2023.05.18 |
[SWEA / Java] 1208번: Flatten (D3) (0) | 2023.05.18 |
[SWEA / Java] 1206번: View (D3) (0) | 2023.05.18 |
[프로그래머스 / Java] 구명보트 (Lv.2) (0) | 2023.05.06 |