genres: ["classic", "pop", "classic", "classic", "pop"]
plays: [500, 600, 150, 800, 2500]
return: [4, 1, 3, 0]
genrePlayMap: Map<String, Integer> 타입에 <장르, 재생 횟수> 값 담기 genrePQMap: Map<String, PriorityQueue<Song> 타입에 <장르, 장르별 노래 목록의 PQ> 값 담기genrePlayMap의 keySet을 통해 장르들의 키 값을 ArrayList로 감싸 List<String> genreOrder에 담기List<Integer> result 선언List<String> genreOrder를 for문으로 순회하며 각 장르의 pq에서 2번씩 pollList<Integer> result를 stream을 통해 int[] 배열로 만들기import java.util.*;
class Solution {
// 0. Song 클래스 정의
static class Song {
int id;
int plays;
Song(int id, int plays) {
this.id = id;
this.plays = plays;
}
}
public int[] solution(String[] genres, int[] plays) {
Map<String, Integer> genrePlayMap = new HashMap<>();
Map<String, PriorityQueue<Song>> genrePQMap = new HashMap<>();
// 1. 장르별 총 재생수 & 곡 리스트 구성
for (int i = 0; i < genres.length; i++) {
String genre = genres[i];
int playCount = plays[i];
// 장르별 총 재생수 관리
if (genrePlayMap.containsKey(genre)) {
int currentTotal = genrePlayMap.get(genre);
genrePlayMap.put(genre, currentTotal + playCount);
} else {
genrePlayMap.put(genre, playCount);
}
// 장르별 PQ가 없다면 만들기
if (!genrePQMap.containsKey(genre)) {
genrePQMap.put(genre, new PriorityQueue<>(
(s1, s2) -> {
if (s1.plays == s2.plays) return s1.id - s2.id; // id 오름차순
return s2.plays - s1.plays; // plays 내림차순
}
));
}
// 있다면 장르별 PQ에 곡 추가
genrePQMap.get(genre).offer(new Song(i, playCount));
}
// 2. 장르 정렬 (총 재생수 내림차순)
List<String> genreOrder = new ArrayList<>(genrePlayMap.keySet());
genreOrder.sort((a, b) -> genrePlayMap.get(b) - genrePlayMap.get(a));
// 3. PQ에서 상위 곡 2개만 꺼내기
List<Integer> result = new ArrayList<>();
for (String g : genreOrder) {
PriorityQueue<Song> pq = genrePQMap.get(g);
if (!pq.isEmpty()) result.add(pq.poll().id);
if (!pq.isEmpty()) result.add(pq.poll().id);
}
// [output]
return result.stream().mapToInt(i -> i).toArray();
}
}
| 단계 | 복잡도 |
|---|---|
| 장르별 총 재생수 계산 | O(N) |
| 장르별 PQ 삽입 | O(N log N) |
| 장르 정렬 | O(G log G) (G = 장르 개수) |
| 각 장르에서 곡 2개 선택 | O(G log N) |
| 총합 | O(N log N) |
// 기존 방식
Comparator<Integer> comp = new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
};
// 람다식 방식
Comparator<Integer> comp = (a, b) -> b - a;
List<Integer> -> int[] 타입 변환return result.stream()
.mapToInt(i -> i)
.toArray();
리스트를 스트림으로 변환한 후
Integer 객체를 기본 int로 언박싱하여 (IntStream 생성)
toArray()를 통해 IntStream을 int[]로 변환함.
이 코드에서 잘못된 부분이나 개선할 점이 있다면 언제든지 댓글로 알려주세요.
알고리즘을 작성하면서 더 좋은 코드를 만들 수 있도록 도와주시면 정말 감사하겠습니다! 🙂