T_era
[JAVA] 해시 : 베스트앨범 본문
문제 내용

이 문제를 풀기 위한 방법으로 재생횟수를 기준으로 정렬한 노래의 정보를 데이터로 만들고
총합재생수를 정렬한 데이터를 만든 뒤, 총합재생수가 가장 높은 장르에서 먼저 정렬한 데이터의 위에서 2개만 가져오는 과정을 생각했다.
일단 노래의 번호와 재생 수를 저장할 클래스를 하나 만들었다.
class SongInfo {
int index;
int play;
public SongInfo(int index, int play) {
this.index = index;
this.play = play;
}
}
그리고 장르를 키값으로 SongInfo를 리스트화해서 저장하는 songs
장르를 키값으로 총합 재생수를 저장하는 totalOfSong을 선언하고
아래 코드와 같이 데이터를 분류했다
HashMap<String, List<SongInfo>> songs = new HashMap<>();
HashMap<String, Integer> totalOfSong = new HashMap<>();
for (int i = 0; i < genres.length; i++) {
totalOfSong.put(genres[i], totalOfSong.getOrDefault(genres[i], 0) + plays[i]);
songs.computeIfAbsent(genres[i], k -> new ArrayList<>()).add(new SongInfo(i, plays[i]));
}
근데 List를 통해 값을 넣으려하니 방법이 안떠올라서 조금 찾아보다
songs.computeIfAbsent(genres[i], k -> new ArrayList<>()).add(new SongInfo(i, plays[i]));
이 코드를 알게 되었다
computeIfAbsent(Key, mappingFunction)은 키가 없을 때 새로운 키를 만들어주는 메서드인데
List의 경우 new로 초기화해야하는 과정이 필요해 k -> new ArrayList<>() 이 람다식을 통해
키가 처음 호출됐을 경우 ArrayList를 새로 생성하는 과정을 진행해준다.
그리고 처음 생각했던데로 장르별로 높은 재생수 순으로 정렬을 진행했다
추가적으로 재생 수가 같을 경우 index가 낮은 순으로 정렬되게 했다
for (String genre : songs.keySet()) {
songs.get(genre).sort((o1, o2) -> {
if (o1.play != o2.play) return o2.play - o1.play;
return o1.index - o2.index;
});
}
그리고 총합 재생수를 기준으로 키값을 정렬했다
ArrayList<String> totals = new ArrayList<>(totalOfSong.keySet());
totals.sort((o1, o2) -> totalOfSong.get(o2) - totalOfSong.get(o1));
ArrayList<Integer> answer = new ArrayList<>();
마지막으로 totals들어간 키값의 순서를 기준으로 songs에서 index만 가져오는 과정만 진행하면 풀이가 끝난다
단, 노래당 두개씩만 선택할 수 있다고 했으니 count를 추가해 2번 저장하면 다음 키로 이동하게 했다
for (String genre : totals) {
int count = 0;
for (SongInfo value : songs.get(genre)) {
if (count < 2) {
answer.add(value.index);
count++;
} else {
break;
}
}
}
마지막으로 ArrayList를 배열화해서 반환하면 종료된다
return answer.stream().mapToInt(Integer::intValue).toArray();
전체 코드
import java.util.*;
class Solution {
public int[] solution(String[] genres, int[] plays) {
HashMap<String, List<SongInfo>> songs = new HashMap<>();
HashMap<String, Integer> totalOfSong = new HashMap<>();
// 노래의 타입별 전체 재생횟수를 저장
// 노래의 번호와 재생횟수를 리스트화하여 저장
for (int i = 0; i < genres.length; i++) {
totalOfSong.put(genres[i], totalOfSong.getOrDefault(genres[i], 0) + plays[i]);
songs.computeIfAbsent(genres[i], k -> new ArrayList<>()).add(new SongInfo(i, plays[i]));
}
// 타입별 노래 재생횟수 내림차순으로 정렬하고 재생횟수가 같으면 번호를 오름차순으로 정렬
for (String genre : songs.keySet()) {
songs.get(genre).sort((o1, o2) -> {
if (o1.play != o2.play) return o2.play - o1.play;
return o1.index - o2.index;
});
}
// 노래의 총합 재생횟수를 내림차순 정렬
ArrayList<String> totals = new ArrayList<>(totalOfSong.keySet());
totals.sort((a, b) -> totalOfSong.get(b) - totalOfSong.get(a));
ArrayList<Integer> answer = new ArrayList<>();
// 정렬된 키값을 통해 재생횟수가 정렬된 songs에서 해당 키값의 2개씩만 저장하여 반환
for (String genre : totals) {
int count = 0;
for (SongInfo value : songs.get(genre)) {
if (count < 2) {
answer.add(value.index);
count++;
} else {
break;
}
}
}
// Integer타입 리스트를 int 배열로 변환
return answer.stream().mapToInt(Integer::intValue).toArray();
}
}
// 노래의 번호와 재생횟수
class SongInfo {
int index;
int play;
public SongInfo(int index, int play) {
this.index = index;
this.play = play;
}
}'Programing > Programers' 카테고리의 다른 글
| [JAVA] 큐 : 기능개발 (0) | 2025.04.14 |
|---|---|
| [JAVA] 스택 : 같은 숫자는 싫어 (0) | 2025.04.14 |
| [JAVA] 해시 : 의상 (0) | 2025.04.14 |
| [JAVA] 해시 : 전화번호 목록 (0) | 2025.04.14 |
| [JAVA] 해시 : 포켓몬 (0) | 2025.04.14 |