siino's 개발톡

[프로그래머스] 베스트앨범 - Java 본문

코딩테스트/프로그래머스

[프로그래머스] 베스트앨범 - Java

siino 2024. 3. 7. 16:17

https://school.programmers.co.kr/learn/courses/30/lessons/42579

 

문제를 간략히 설명하자면 genres[]와 plays[] 배열이 주어지고, 해당 장르가 플레이된 횟수(내림차순)으로 정렬 한 후에 각 장르에서 많이 플레이 된 곡 top2를 뽑아내면 되는 문제입니다.

 

제가 풀이한 방법은 각 장르의 플레이 된 횟수를 기록할 Map<String, Integer> genreCount 와 각 장르별 곡의 정보를 저장할 Map<String, Map<Integer, Integer>>를 선언하여 문제를 해결했습니다.

 

여기서 말하는 곡의 정보는 (music id, 플레이된 횟수)를 기록합니다.

Map과 관련된 내장 함수 computeIfAbsent(), merge(), getOrDefault()를 활용하여 조금 더 깔끔하게 코드를 작성할 수 있었습니다.

import java.util.*;
import java.util.stream.*;
import java.util.stream.Collectors;
class Solution {
   public int[] solution(String[] genres, int[] plays) {

        //장르 카운트
        Map<String, Integer> genreCount = new HashMap<>();
        for(int i=0; i<genres.length; i++){
            genreCount.put(genres[i], genreCount.getOrDefault(genres[i], 0) + plays[i]);
        }

        //각 장르별 플레이
        Map<String, Map<Integer, Integer>> playCount = new HashMap<>();
        for(int i=0; i<genres.length; i++){
            playCount.computeIfAbsent(genres[i], k -> new HashMap<>()).put(i, plays[i]);
        }

        List<String> genresOrderByDesc = genreCount.keySet().stream()
                                                   .sorted(Comparator.comparing(s -> genreCount.get(s)).reversed())
                                                   .collect(Collectors.toList());
        List<Integer> answer = new ArrayList<>();

        for(String genre: genresOrderByDesc){
            Map<Integer, Integer> idAndPlays = playCount.get(genre);
            List<Integer> keys = idAndPlays.keySet()
                                           .stream()
                                           .sorted(Comparator.comparing(
                                                                 (Integer i) -> idAndPlays.get(i))
                                                             .reversed()
                                                             .thenComparing(i -> i))
                                           .limit(2)
                                           .collect(Collectors.toList());
            answer.addAll(keys);
        }
        return answer.stream().mapToInt(i->i).toArray();
    }
}