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

2022. 2. 11. 13:02알고리즘/프로그래머스

반응형

문제 링크

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

 

코딩테스트 연습 - 베스트앨범

스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가

programmers.co.kr

노래를 수록하는 기준에 따라 차근차근 풀면 생각보다 어렵지 않은 문제.

 

1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.

해시맵을 <genres, plays>에 곡을 담아 정렬한 후 가장 많이 재생된 순으로 장르를 구한다.

해당 장르를 String []sortedGenres 에 담는다.

 

2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.

1번 기준으로 정렬된 장르를 두고, 해당 장르에 속하는 노래를 <해당 노래의 index, 재생 횟수(plays)> 에 담아 정렬한다.

앞 2개가 해당 장르에서 가장 많이 재생된 노래이며 해당 key에 index를 담고 있다.

ex) sortedGenres[0] == classic인 경우

genres :  ["classic", "pop", "classic", "classic", "pop"]         plays  :   [500, 600, 150, 800, 2500]

<classic, 500> <classic, 150> <classic, 800>  =>  <classic, 800> <classic, 500> <classic, 150> 정렬

 

3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
2번에서 담을 때부터 index순으로 조회하기 때문에 고려할 필요가 없다.

 

import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.LinkedList;
import java.util.Comparator;
class Solution {
    public int[] solution(String[] genres, int[] plays) {
        int[] answer = {};
        ArrayList<Integer> ans = new ArrayList<>();
        HashMap<String, Integer> map = new HashMap<>();
        
        for (int i = 0; i < genres.length; i++) {
            if (map.containsKey(genres[i])) {
                int play = map.get(genres[i]);
                map.put(genres[i], play + plays[i]);
            }
            else
                map.put(genres[i], plays[i]);
        }
        String []sortedGenres = new String[map.size()];
        List<Map.Entry<String, Integer>> entryList = new LinkedList<>(map.entrySet());
        entryList.sort(new Comparator<Map.Entry<String, Integer>>() {
        @Override
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            return o2.getValue() - o1.getValue();
            }
        });
        int i = 0;
        for(Map.Entry<String, Integer> entry : entryList){
            System.out.println("key : " + entry.getKey() + ", value : " + entry.getValue());
            sortedGenres[i++] = entry.getKey();
        }
        // 모든 장르를 돌며 해시맵 <인덱스, plays수>를 넣는다.
        HashMap<Integer, Integer> mostSong = new HashMap<>();
        for (int j = 0; j < sortedGenres.length; j++) {
            for (int z = 0; z < genres.length; z++) {
                if (genres[z].equals(sortedGenres[j])) {
                    mostSong.put(z, plays[z]);
                }
            }
            // play 순서별로 정렬
            List<Map.Entry<Integer, Integer>> entryList2 = new LinkedList<>(mostSong.entrySet());
            entryList2.sort(new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o2.getValue() - o1.getValue();
                }
            });
            i = 0;
            for(Map.Entry<Integer, Integer> entry : entryList2){
                if (i == 2)
                    break;
                ans.add(entry.getKey());
                i++;
            }   
            mostSong.clear();
        }
        answer = new int[ans.size()];
        for (i = 0; i < ans.size(); i++) {
            answer[i] = ans.get(i);
        }
        return answer;
    }
}

자바는 역시 코드가 길다.. 이 문제를 풀면서 처음으로 해시맵 정렬에 대한 공식을 찾아볼 수 있었다.

Comparator에 대해 따로 정리해두면 좋을 듯 하다... 언제가 될 진 모르겠지만..^_^..