💡 문제
💬 입출력 예시
📌 풀이(소스코드)
import java.util.*;
import java.util.stream.Collectors;
class Solution {
public int[] solution(String[] genres, int[] plays) {
List<Integer> answer = new ArrayList<>();
Map<String, Integer> genreMap = new HashMap<>();
Map<String, HashMap<Integer, Integer>> playsMap = new HashMap<>();
for (int i = 0; i < plays.length; i++) {
int play = plays[i];
String genre = genres[i];
genreMap.put(genre, genreMap.getOrDefault(genre, 0) + play);
playsMap.putIfAbsent(genre, new HashMap<>());
playsMap.get(genre).put(i, play);
}
List<String> genreList = new ArrayList<>(genreMap.keySet());
genreList.sort(Comparator.comparingInt(genreMap::get).reversed());
for (String genre : genreList) {
Map<Integer, Integer> map = playsMap.get(genre);
List<Integer> playList = new ArrayList<>(map.keySet());
playList.sort(Comparator.comparingInt(map::get).reversed());
playList.stream().map(answer::add).limit(2).collect(Collectors.toList());
}
return answer.stream().mapToInt(Integer::intValue).toArray();
}
}
📄 해설
접근
- 이번 문제는 프로그래머스 level 3 문제로, 접근도 제대로 못하고 다른 코드를 봤다.
- 솔직히 많이 많이 많이 어려우나, 코드와 함께 설명을 보면 이해하기 어려운 것은 아니다.
- 두 개의 맵을 사용하고, 하나의 맵은 value 로 맵을 가진다는 것을 접근했다면 구현이 가능했을 것 같은 문제.
- 문제의 조건은 아래와 같다.
- 속한 노래가 많이 재생된 장르를 먼저 수록
- 장르 내에서 많이 재생된 노래를 먼저 수록
- 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록
- 문제의 조건 만족을 위해서는 아래의 작업을 수행해야한다.
- 장르별로 전체 재생 횟수를 구하고, 장르별 전체 재생 횟수를 기준으로 장르 리스트를 정렬한다.
- 정렬된 장르의 노래별 재생횟수를 구해서, 노래별 재생횟수를 기준으로 노래 리스트를 정렬한다.
과정
- 장르별 전체 재생 횟수와 장르에 속하는 노래별 재생횟수를 구하는 과정을 한 번에 처리한다.
이를 위해 두 개의 Map
을 사용한다.
- 장르별 전체 재생 횟수는
<String, Integer>
맵에, 장르에 속하는 노래별 재생횟수는 <String, HashMap<Integer, Integer>>
맵에 저장한다.
- 장르별 전체 재생 횟수가 저장된 맵의 keySet 이 장르 목록이므로, 이를
genreList
에 담고, 재생횟수로 내림차순 정렬한다.
genreList
를 순회하며 추가적인 정렬을 수행해준다.
- 장르에 속하는 노래별 재생횟수가 저장된 맵 내의
<Integer, Integer>
맵의 keySet
이 노래 번호 목록이므로, 역시 이를 playList
에 담고, 재생횟수로 내림차순 정렬한다.
- 정렬 후, 가장 많이 재생된 노래 두개를
answer
에 추가한다.
- 내림차순 정렬이므로, 앞의 두개를 넣어주면 된다. (오름차순이라면 뒤의 두개)