https://school.programmers.co.kr/learn/courses/30/lessons/42579
import java.util.*;
class Solution {
static HashMap<Integer, List<Music>> musicByGenre = new HashMap<>(); //재생횟수를 장르 고유 인덱스로 사용
static Map<String, Integer> genreCnt;
public int[] solution(String[] genres, int[] plays) {
List<Integer> ans = new ArrayList<>();
genreCnt = countGenrePlay(genres, plays);
makeMusicList(genres, plays);
//총 재생 횟수 내림차순 정렬
List<Integer> cntList = new ArrayList<>(genreCnt.values());
cntList.sort(Collections.reverseOrder());
for (int key : cntList) {
if(musicByGenre.get(key).size() == 1) {
ans.add(musicByGenre.get(key).get(0).idx); continue;
}
Collections.sort(musicByGenre.get(key));
musicByGenre.get(key).subList(0, 2).forEach(m -> ans.add(m.idx));
}
return ans.stream().mapToInt(i -> i).toArray();
}
private void makeMusicList(String[] genres, int[] plays) {
for (int i = 0; i < plays.length; i++) {
int totalCnt = genreCnt.get(genres[i]);
if (!musicByGenre.containsKey(totalCnt)) {
musicByGenre.put(totalCnt, new ArrayList<>());
}
musicByGenre.get(totalCnt).add(new Music(i, plays[i]));
}
}
private Map<String, Integer> countGenrePlay(String[] genres, int[] plays) {
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < genres.length; i++) {
if (!map.containsKey(genres[i])) {
map.put(genres[i], plays[i]);
continue;
}
map.put(genres[i], map.get(genres[i]) + plays[i]);
}
return map;
}
class Music implements Comparable<Music> {
int idx;
int playCnt;
public Music(int idx, int playCnt) {
this.idx = idx;
this.playCnt = playCnt;
}
@Override
public int compareTo(Music o) {
if(this.playCnt > o.playCnt) return -1;
else if(this.playCnt < o.playCnt) return 1;
else {
if(this.idx < o.idx) return -1;
else if(this.idx > o.idx) return 1;
}
return 0;
}
}
}
- 정렬 기준 1. 장르 총 재생 횟수 2. 곡 고유 재생 횟수 3. 곡 고유 번호
- 각 장르마다 곡은 2개 이하로 선택 == 모든 장르마다 1개 이상 선택
- 장르마다 총 재생 횟수가 다름 == 총 재생 횟수가 인덱스가 될 수 있음
위 사항들을 토대로 앨범을 구성하기 위해 2가지 Collection을 사용할 수 있음
1. Map<String, Integer> genreCnt : 장르별 누적 재생 횟수, key(장르명) - value(총 재생 횟수)
2. Map<Integer, List<Music>> musicByGenre : 각 장르재생 횟수(=장르명)(key) - 장르에 속한 음악 객체(value)
- 장르 총 재생횟수를 key로 설정해서 추후 재생횟수 내림차순으로 뽑기 쉽게 함
# 진행 과정
- 한 번 돌면서 장르 별 누적 횟수 map 구함
- 다시 돌면서 누적 횟수를 key로 한 뒤, 음악 객체 생성해서 장르 별 리스트에 할당
- 이때 Music class에서 Comparable을 implement 하여 정렬 기준 별도로 설정 : (1) 재생 횟수 내림차순 (2) 고유 넘버 오름차순
- musicByGenre를 장르별 재생 횟수 기준 내림차순 정렬 한 뒤, 각 장르마다 2개씩 뽑아 answer에 넣어줌
- 장르의 음악이 1개인 경우, 정렬 없이 바로 뽑아서 넣음
- 장르의 음악이 2개 이상인 경우, List<Music>을 정렬해준 뒤, 2개 뽑아 idx를 추출해 넣음
다른 답안을 보니 collect의 groupBy를 활용해서 Map을 생성한 뒤, 그것을 다시 stream으로 돌려서 결과를 도출하는 것을 보았다. stream과 Collector에 대해 이해하고 잘 써먹을 필요성을 느낌...ㅎㅎ
'Algorithm > Programmars' 카테고리의 다른 글
[JAVA] Lv3. 디스크 컨트롤러 - 프로그래머스 (1) | 2023.12.15 |
---|---|
[JAVA] Lv2. 프로세스 - 프로그래머스 (0) | 2023.12.14 |
[JAVA] Lv2. 다리를 지나는 트럭 - 프로그래머스 (0) | 2023.12.12 |
[JAVA] Lv.2 전화번호 목록 - 프로그래머스 (1) | 2023.12.11 |
[JAVA] Lv.2 타겟 넘버 - 프로그래머스 (1) | 2023.12.07 |