티스토리 뷰
programmers.co.kr/learn/courses/30/lessons/42579
문제는 위와 같으며, 장르별 노래의 재생 횟수의 합을 저장한 Map과 장르별 노래 리스트를 저장한 Map을 만들어서 정렬함으로써 문제를 해결하였습니다.
베스트앨범에 들어갈 노래의 조건을 하나씩 살펴보겠습니다.
1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
이 조건을 확인하기 위해, 주어진 노래를 차례로 확인하면서 장르를 key로 하고 해당 노래가 재생된 횟수의 합을 value로 하여 Map에 저장합니다. 이후 값(value)을 기준으로 내림차순 정렬을 하여 가장 많이 재생된 장르부터 순서대로 노래를 확인할 수 있도록 하였습니다.
2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
가장 많이 재생된 장르부터 순서대로 노래 목록을 가져온 뒤, 해당 목록에 포함된 노래들을 재생 횟수를 기준으로 내림차순 정렬합니다. 재생 횟수가 같은 경우에는 먼저 추가된 순서대로 정렬되기 때문에 자동으로 고유 번호가 낮은 노래 순으로 정렬됩니다. 그런다음 최대 2개까지 노래 리스트를 반복하면서 노래의 고유 번호를 정답 리스트에 저장합니다.
마지막으로 정답 리스트를 int 배열로 변경하여 반환합니다.
Java 코드는 다음과 같습니다.
import java.util.*;
class Solution {
public int[] solution(String[] genres, int[] plays) {
ArrayList<Integer> answer = new ArrayList<>();
Map<String, Integer> playCountPerGenres = new LinkedHashMap<>(); // 장르별 재생 횟수 합
Map<String, LinkedList<Song>> songsByGenres = new LinkedHashMap<>(); // 장르별 노래 리스트
// 주어진 배열을 차례로 확인하면서
for (int i = 0; i < genres.length; i++) {
// 장르를 key로 하고 해당 장르의 노래 재생 횟수의 합을 값으로 하여 저장
playCountPerGenres.put(genres[i], playCountPerGenres.getOrDefault(genres[i], 0) + plays[i]);
// 장르를 key로 하고 해당 장르의 노래를 리스트로 저장
Song song = new Song(i, plays[i]);
LinkedList<Song> tmp = songsByGenres.getOrDefault(genres[i], new LinkedList<>());
tmp.add(song);
songsByGenres.put(genres[i], tmp);
}
// 재생 횟수를 기준으로 장르를 내림차순 정렬
Map<String, Integer> sortedPlayCountPerGenres = sortByPlayCount(playCountPerGenres);
// 가장 많이 재생된 장르별로 차례대로 확인하면서
for (String key : sortedPlayCountPerGenres.keySet()) {
// 해당 장르에 속한 노래 리스트를 재생 횟수가 많은 순으로 정렬하여 찾은 뒤
List<Song> songs = sortByPlays(songsByGenres.get(key));
// 장르별 최대 2개 노래의 고유 번호를 정답 리스트에 저장
for (int i = 0; i < songs.size() && i < 2; i++) {
answer.add(songs.get(i).num);
}
}
return answer.stream().mapToInt(i -> i).toArray();
}
// 가장 많이 재생된 장르 순으로 정렬
private static Map<String, Integer> sortByPlayCount(Map<String, Integer> map) {
List<Map.Entry<String, Integer>> entries = new LinkedList<>(map.entrySet());
entries.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));
Map<String, Integer> result = new LinkedHashMap<>();
for (Map.Entry<String, Integer> entry : entries) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
// 한 장르에서 가장 많이 재생된 노래 순으로 정렬
private static List<Song> sortByPlays(List<Song> list) {
list.sort(new Comparator<Song>() {
@Override
public int compare(Song o1, Song o2) {
return o2.plays - o1.plays;
}
});
return list;
}
// 노래 객체
private static class Song {
private final int num; // 고유 번호 (인덱스)
private final int plays; // 재생 횟수
public Song(int num, int plays) {
this.num = num;
this.plays = plays;
}
}
}
'알고리즘' 카테고리의 다른 글
[프로그래머스] 네트워크 (0) | 2021.04.02 |
---|---|
[프로그래머스] 주식 가격 (0) | 2021.04.02 |
[프로그래머스] 위장 (0) | 2021.03.31 |
[알고리즘 / 백준] 1644 - 소수의 연속합 (0) | 2021.03.01 |
[알고리즘 / 백준] 2470 - 두 용액 (0) | 2021.03.01 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- CodeCommit
- DFS
- Baekjoon
- BFS
- 순열
- EC2
- string
- ionic
- 소수
- map
- java
- programmers
- 수학
- CodeDeploy
- Dynamic Programming
- 프로그래머스
- spring
- 조합
- AWS
- SWIFT
- 에라토스테네스의 체
- permutation
- Combination
- sort
- search
- Algorithm
- array
- CodePipeline
- cloudfront
- ECR
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함