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

프로그래머스 - 베스트 앨범 문제 - 자바

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

 

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

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

programmers.co.kr

 

장르, 장르별 총재생횟수

장르, 장르에 속한 노래

이 두가지로 map을 만들고

셋팅한 뒤 장르, 장르별 총재생을 총재생에 따라서 정렬한 뒤 각 장르별 2개까지만 추출한다.

 

아래의 코드 중 조심해야하는 부분은

getOrDefault 메서더는 해당 키값이 이미 map에 존재하면 해당 값을 아니면 2번째 매개변수로 적은 기본값으로 설정한다. 아래의 코드에서는 기본값을 0으로 하였고 그 뒤로 +count를 통해서 기존값에 추가하였다.

computeIfAbsent의 경우 해당 키값으로 없는 경우 두번째 인자로 준 function을 실행하여 기본값을 설정한다.

또한 해당 키값의 value값을 리턴한다.

아래 코드에서는 새로운 ArrayList를  만들어서 새로운 노래를 추가하는 형태이다.

for(int i = 0; i < genres.length; i++) {
    String name = genres[i]; // 장르
    int count = plays[i]; // 재생 횟수
    
    // 장르별 총 재생 횟수 등록
    genre_total.put(name, genre_total.getOrDefault(name, 0) + count);
    
    // 장르별 노래 등록
    genre_songs.computeIfAbsent(name, s -> new ArrayList<>()).add(new Song(i, count));
}

 

import java.util.*;

// 프로그래머스 베스트 앨범 문제
class Song implements Comparable<Song>{
    int idx;
    int count;

    public Song(int idx, int count) {
        this.idx = idx;
        this.count = count;
    }

    public int compareTo(Song other) {
        if(this.count == other.count) {
            return Integer.compare(this.idx, other.idx);
        }
        return Integer.compare(other.count, this.count);
    }
}

class BestAlbum {
    public int[] solution(String[] genres, int[] plays) {
        HashMap<String, Integer> genre_total = new HashMap<>(); // 장르 , 장르별 총 재생 횟수
        HashMap<String, ArrayList<Song>> genre_songs = new HashMap<>(); // 장르, 장르에 속한 노래
        ArrayList<Integer> result = new ArrayList<>();

        for(int i = 0; i < genres.length; i++) {
            String name = genres[i]; // 장르
            int count = plays[i]; // 재생 횟수

            // 장르별 총 재생 횟수 등록
            genre_total.put(name, genre_total.getOrDefault(name, 0) + count);

            // 장르별 노래 등록
            genre_songs.computeIfAbsent(name, s -> new ArrayList<>()).add(new Song(i, count));
        }

        // 장르별 총 재생 횟수를 내림차순으로 정렬
        List<String> keySetList = new ArrayList<>(genre_total.keySet());
        keySetList.sort((o1, o2) -> (genre_total.get(o2).compareTo(genre_total.get(o1))));

        // 정렬된 장르를 순회
        for(String key : keySetList) {
            // 해당 잘르에 속한 노래 목록
            ArrayList<Song> songs = genre_songs.get(key);
            // 정렬 (횟수에 따라서, 횟수가 같으면 인덱스 순)
            Collections.sort(songs);

            // 노래 목록을 순회하면서 최대 2개 까지 선택
            int index = 0;
            for (Song song : songs) {
                if(index > 1) break;
                result.add(song.idx);
                index++;
            }
        }

        // ArrayList -> int[]
        int[] answer = new int[result.size()];
        int index = 0;
        for(Integer idx : result) {
            answer[index] = idx;
            index++;
        }

        return answer;
    }
}