Old/Algorithms

[JAVA] 프로그래머스 : 베스트앨범 (코딩테스트 고득점 kit > 해쉬)

유뱅유뱅뱅 2020. 7. 14. 23:18

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

 

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

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

programmers.co.kr

여러 자료구조를 연결하여 구현하였음

문제 설명 순서의 로직을 참고하여 그 순서대로 구현하려고 하였음

문제의 1번 과정인 장르별 총 플레이수 별로 저장한 자료구조와
문제의 2,3번 과정에 필요한 전체 노래 자료구조를 구현하여 각각을 정렬함

그 후 베스트 앨범에 들어갈 수 있도록 각 장르별 2곡씩 뽑음

* Comparable의 compareTo를 사용하여 내림차순, 오름차순을 구현하였음
오름 차순의 경우 o1.compareTo(o2)
내림 차순의 경우 o2.compareTo(o1)

import java.util.*;
// 베스트앨범
// 장르별 가장 많이 재생된 노래 2개씩 모아 베스트 앨범 출시
class Solution {
    static class Song implements Comparable<Song>{
        int sId;
        String genre;
        int play;
        
        Song(int sId, String genre, int play){
            this.sId = sId;
            this.genre = genre;
            this.play = play;
        }
        
        @Override
        public int compareTo(Song o){
            // 재생 수 내림차순
            int result = (o.play) - (this.play);
            
            // 재생수 같을 때 고유 번호 오름차순
            if(result == 0){
                result = (this.sId) - (o.sId);
            }
            
            return result;
        }
    }
    
    // 입력 테스트케이스 크기가 10^4
    public int[] solution(String[] genres, int[] plays) {
        
        // 해쉬 맵으로 genres별 총 재생 수 put
        // classic 1450    pop 3100
        Map<String, Integer> map = new HashMap<>();
        for(int i=0; i<genres.length; i++){
            if(map.containsKey(genres[i])){
                map.put(genres[i], (map.get(genres[i]) + plays[i]));
            }
            else{
                map.put(genres[i], plays[i]);
            }
        }
        
        // value(총 재생 수)에 따른 내림차순 정렬 (pop | classic)
        List<String> genreKeyList = new ArrayList<>(map.keySet());
        Collections.sort(genreKeyList, (o1, o2) -> (map.get(o2).compareTo(map.get(o1))));
        /*for(String key : genreKeyList) {
			System.out.println("key : " + key + " / " + "value : " + map.get(key));
		}*/
        
        // Song 클래스 만들어서 Array List에 다 넣기 (id, genres, plays)
        List<Song> songList = new ArrayList<>();
        for(int i=0; i<genres.length; i++){
            songList.add(new Song(i, genres[i], plays[i]));
        }
        // plays 역순 정렬 시키기 & id 작은 순(Song 클래스에서 compareTo 작성)
        Collections.sort(songList);
        /*for(Song song : songList){
            System.out.println(song.sId + ", " + song.play);
        }*/
        
        // 정렬된 genreKeyList(장르) 순서대로 // 플레이수 가장 많은 2개(미리정렬해놓은) 꺼내서 result List에 add 
        List<Integer> result = new ArrayList<>();
        int cnt;
        for(String key: genreKeyList){
            cnt = 0;
            for(Song song: songList){
                if(key.equals(song.genre)){
                    result.add(song.sId);
                    cnt++;
                }
                if(cnt==2)
                    break;
            }
        }
        
        // ArrayList result -> Array answer
        int[] answer = new int[result.size()];
        for(int i=0; i<answer.length; i++){
            answer[i] = (int)result.toArray()[i];
        }
        
        return answer;
    }
}