프로그래머스 > Hash > 베스트앨범
https://programmers.co.kr/learn/courses/30/lessons/42579
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.
genres | plays | return |
---|---|---|
["classic", "pop", "classic", "classic", "pop"] | [500, 600, 150, 800, 2500] | [4, 1, 3, 0] |
HashMap과 ArrayList자료구조 2가지를 사용해서 풀었다.
HashMap<String, Integer> map = new HashMap<>();
ArrayList<String> genre_list = new ArrayList<>();
int genres_len = genres.length;
for(int i=0; i<genres_len; i++) {
if( !map.containsKey(genres[i]) ) {
genre_list.add(genres[i]);
}
map.put(genres[i], map.getOrDefault(genres[i], 0)+plays[i]);
}
먼저 genres[]
배열에 어떤 장르별 총 재생횟수를 파악하기 위해 HashMap을 사용한다.
그리고 map
에 포함되지 않은 장르는 genre_list
에 넣는다
장르가 중첩되지 않도록 하나만 들어 갈 수 있도록 만든다.
// 장르만 담긴 genre_list를 재생횟수가 높은 순으로 정렬
Collections.sort(genre_list, (o1, o2) -> map.get(o2) - map.get(o1));
그리고 각 장르의 종류가 들은 genre_list
에서 각 장르별 전체 재생 횟수가 가장 많은 순서대로 정렬하기 위해 Collections.sort()를 사용한다.
ArrayList<Music> result = new ArrayList<>();
for(String genr : genre_list) {
ArrayList<Music> list = new ArrayList<>();
for(int i=0; i<genres_len; i++) {
if(genres[i].equals(genr)) {
list.add(new Music(genr, i, plays[i]));
}
}
Collections.sort(list, (o1, o2) -> o2.Streaming - o1.Streaming);
// 장르에 포함된 곡을 2개 result에 담기
result.add(list.get(0));
// 장르에 포함된 곡이 1개 일 경우 하나만 포함
if(list.size() > 1) {
result.add(list.get(1));
}
}
결과 값을 담을 result
Music객체형 new ArrayList<Music>
을 생성해준다.
Music 객체는
genre_name
id
Streaming
genre_list
에서 나오는 각 장르의 이름 값인 genr
의 값을 기준으로
genres
의 배열에 있는 값과 genr
가 일치하는 값을 list에 Music객체형으로 넣어준다.
Ex) 우리가 아까 gener_list
에서 정렬을 해준 상태이고, genre_list
에서 pop이 가장 앞에 있으니까 pop이 가장 먼저 나오게 된다. genres[]
배열에서 pop과 같은 장르만을 list
에 집어 넣는다ㅏ.
이렇게 하면 pop장르의 노래들만 genres[]
배열에서 꺼내서 list에 넣을 수 있다.
다음이 classic 장르니까 classic 장르만 genres[]
배열에서 찾아서 list
에 넣게 된다.
이렇게 하면 우리는 아까 미리 각 장르를 전체 재생횟수 순으로 미리 정렬을 해두었기 때문에 순서대로 result
에 값을 넣어서 출력만 하면된다.
여기서 놓치면 안되는 부분은 문제에서 장르 내에서 곡이 하나 밖에 없을 때는 하나만 출력하라고 했을 때인데 이때는
if(list.size() > 1) {
result.add(list.get(1));
}
해당 조건문을 넣어서 list
에 해당 장르가 한개이상인지 판단해서 result
에 추가하면 된다.
베스트앨범 그렇게 하는 거 아닌데 쿠쿠
import java.util.*; class Solution { static class Music { String genre_name; int id; int Streaming; public Music(String genre_name, int id, int Streaming) { this.genre_name = genre_name; this.id = id; this.Streaming = Streaming; } } public int[] solution(String[] genres, int[] plays) { HashMap<String, Integer> map = new HashMap<>(); ArrayList<String> genre_list = new ArrayList<>(); int genres_len = genres.length; for(int i=0; i<genres_len; i++) { if( !map.containsKey(genres[i]) ) { genre_list.add(genres[i]); } map.put(genres[i], map.getOrDefault(genres[i], 0)+plays[i]); } // 장르만 담긴 genre_list를 재생횟수가 높은 순으로 정렬 Collections.sort(genre_list, (o1, o2) -> map.get(o2) - map.get(o1)); ArrayList<Music> result = new ArrayList<>(); for(String genr : genre_list) { ArrayList<Music> list = new ArrayList<>(); for(int i=0; i<genres_len; i++) { if(genres[i].equals(genr)) { list.add(new Music(genr, i, plays[i])); } } Collections.sort(list, (o1, o2) -> o2.Streaming - o1.Streaming); // 장르에 포함된 곡을 2개 result에 담기 result.add(list.get(0)); // 장르에 포함된 곡이 1개 일 경우 하나만 포함 if(list.size() > 1) { result.add(list.get(1)); } } int result_size = result.size(); int arr[] = new int[result_size]; for(int i=0; i<result_size; i++) { arr[i] = result.get(i).id; } return arr; } }