Cute Dog Bopping Head
본문 바로가기
Code IT/Algorithm

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

by 찾 2021. 8. 14.

 

import java.util.*;

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        //HashMap에 저장
        //key: genre, value: hashmap <고유번호,재생횟수>
        HashMap<String, LinkedHashMap<Integer,Integer>> genresAndPlays = new HashMap<>();
        for(int i =0;i<genres.length;i++){
            LinkedHashMap<Integer,Integer> numAndPlay =new LinkedHashMap<>();
            if(genresAndPlays.containsKey(genres[i])){
                numAndPlay =genresAndPlays.get(genres[i]);
            }
            numAndPlay.put(i,plays[i]);
            genresAndPlays.put(genres[i],numAndPlay);
        }
        
        //많이 재생된 순으로 장르 정렬
        //key: genre, value: 재생횟수의 sum
        LinkedHashMap<String,Integer> genreRank = new LinkedHashMap<>();
        for(int i=0;i<genres.length;i++){
            genreRank.put(genres[i],genreRank.containsKey(genres[i])? genreRank.get(genres[i])+plays[i] : plays[i]);
        }
        //엔트리를 value 값 기준으로 내림차순 정렬
        ArrayList<Map.Entry<String,Integer>> entrylist= new ArrayList<>(genreRank.entrySet());
        entrylist.sort(new Comparator<Map.Entry<String,Integer>>(){
            public int compare(Map.Entry<String,Integer> o1, Map.Entry<String,Integer> o2){
                return o2.getValue() - o1.getValue();
            }
        });
        genreRank.clear();
         for(Map.Entry<String,Integer> entry:entrylist)
                genreRank.put(entry.getKey(),entry.getValue());
        
        
        // 가장 높은 두 개의 play만 남기고 나머지를 삭제.
        for(String genre: genresAndPlays.keySet()){
            LinkedHashMap<Integer,Integer> new_numAndPlay = new LinkedHashMap<>();
            ArrayList<Map.Entry<Integer,Integer>> entrylist_numAndPlay= new ArrayList<>(genresAndPlays.get(genre).entrySet());
            entrylist_numAndPlay.sort(new Comparator<Map.Entry<Integer,Integer>>(){
                public int compare(Map.Entry<Integer,Integer> o1, Map.Entry<Integer,Integer> o2){
                    return o2.getValue() - o1.getValue();
                }
            });
            //같은 재생횟수의 경우: linkedhashmap을 사용했기에 먼저 들어오는 곡이 (고유번호가 빠른 곡이) 남게 됨.
            int index=0;
            for(Map.Entry<Integer,Integer> entry: entrylist_numAndPlay){
                if(index++<2)
                    new_numAndPlay.put(entry.getKey(),entry.getValue());
                else break;
            }
            genresAndPlays.put(genre,new_numAndPlay); 
        }
        
        //arraylist에 저장 후 list로 변환하여 answer 반환
        ArrayList<Integer> result = new ArrayList<>();
        for(String key:genreRank.keySet()){ //많이 재생된 장르 순
            for(Map.Entry<Integer,Integer> entry: genresAndPlays.get(key).entrySet()){
                result.add(entry.getKey());
            }
        }
        
        int answer[] = new int[result.size()];
        int index=0;
        for(int a : result)
            answer[index++] = a;
        return answer;
    }
}

중첩 해시맵을 사용해 풀이했다.

다른 사람들의 코드를 리뷰해보니 굳이 중첩 말고, 그냥 해시맵을 여러개 사용한 것이 더 깔끔해보였다.

- Comparator의 사용법을 좀 더 잘 보자!

- Stream의 사용법을 알아두자!

- map들을 잘 알아두자! (treemap의 사용법 등)

- 주석을 잘 다는 연습을 해보자!

 

댓글