문제
programmers.co.kr/learn/courses/30/lessons/42579
코딩테스트 연습 - 베스트앨범
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가
programmers.co.kr
코드
롸... 진짜 너무 어렵잖응ㅁ..ㅠㅠㅠㅠㅠㅠ
어떤 자료구조를 쓸 지 고르는 것이 정말 어려웠다. (근데 이게 핵심임)
순서는 다음과 같다.
1. id(고유번호), play(재생횟수), genre를 담은 Song 객체를 만든다.
Song 객체는 ArrayList에 삽입한다. 동시에 각 장르별 play를 합산해 HashMap에 기록해준다.
2. 정렬
3. 정렬된 ArrayList를 바탕으로 베스트앨범 수록곡을 선정한다. 이때 장르별 2곡이라는 기준을 만족하기 위해 HashMap으로 장르별 수록곡 수를 저장한다.
import java.util.*;
class Song {
int id, play;
String genre;
Song(int id, int play, String genre){
this.id = id;
this.play = play;
this.genre = genre;
}
}
class Solution {
ArrayList<Integer> bestAlbum; //베스트 앨범 수록곡
ArrayList<Song> songList; //노래 정보를 담은 ArrayList
HashMap<String, Integer> genreMap; //장르와 총 play 수를 담은 HashMap(Key-value)
HashMap<String, Integer> albumMap; //장르별 2곡 기준을 위한 HashMap
public int[] solution(String[] genres, int[] plays) {
bestAlbum = new ArrayList<>();
songList = new ArrayList<>();
genreMap = new HashMap<>();
albumMap = new HashMap<>();
//1. Song 객체를 ArrayList(songList)에 삽입한다.
//동시에 각 장르별 play를 합산해 HashMap(genreMap)에 기록해준다.
for(int i=0; i<genres.length; i++){
int id =i;
int play = plays[i];
String genre = genres[i];
//노래 정보(id, play, genre)를 담아준다.
songList.add(new Song(id, play, genre));
//genreMap에 이미 있는 장르라면
if(genreMap.containsKey(genre)){
genreMap.put(genre, genreMap.get(genre)+play); //원래 있는 play 횟수에 해당 노래의 play 횟수를 더해준다.
}else{
genreMap.put(genre, play); //새로 만듦
}
}
//2. 정렬 (기준 : 속한 노래가 많은 장르 먼저 -> 장르 내에서는 많이 재생된 노래 먼저 -> 장르 내에서 재생 횟수가 같으면 고유 번호가 낮은 것부터)
Collections.sort(songList, (s1, s2) -> {
//장르가 같은 경우
if(s1.genre.equals(s2.genre)){
//플레이 횟수가 같은 경우
if(s1.play == s2.play)
return s1.id-s2.id; //고유번호가 작은 것부터
else
return s2.play-s1.play; //플레이 횟수가 큰 것부터
}else{
return genreMap.get(s2.genre) - genreMap.get(s1.genre);//장르의 총 플레이 횟수가 큰 것부터
}
});
//3. 베스트앨범을 ArrayList(bestAlbum)에 수록. (장르별 2곡이라는 기준을 만족하기 위해 HashMap(albumMap)으로 장르별 수록곡 수를 저장한다.)
for(Song song : songList){
//albumMap에 없던 장르라면
if(!albumMap.containsKey(song.genre)){
albumMap.put(song.genre, 1); //Key인 장르와 Value인 1을 추가한다.
bestAlbum.add(song.id); //수록
}else{
//해당 노래의 장르 내 순서
int genreCnt = albumMap.get(song.genre);
if(genreCnt >= 2)
continue;
else{
albumMap.put(song.genre, genreCnt + 1); //해당 장르 2
bestAlbum.add(song.id); //수록
}
}
}
int[] answer = new int[bestAlbum.size()];
for(int i = 0 ; i < answer.length ; ++i){
answer[i] = bestAlbum.get(i);
}
return answer;
}
}
'Preparing Coding Test > Programmers L3' 카테고리의 다른 글
[Java/프로그래머스/DFS] Level 3: 단어 변환 (0) | 2020.11.06 |
---|---|
[Java/프로그래머스/DFS] 여행경로 (0) | 2020.11.05 |
[Java/프로그래머스/BFS] 네트워크 (0) | 2020.10.29 |
[Java/프로그래머스/힙(Heap)] 이중우선순위큐 (0) | 2020.10.27 |
[Java/프로그래머스/힙(Heap)] 디스크 컨트롤러 (0) | 2020.10.20 |