제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

두번의 정렬을 이용합니다. 장르 별로 정렬을 이용하고, 장르 내에 앨범 별로 정렬을 이용합니다. 

소스코드

import java.util.*;

class Solution {
    static class Album implements Comparable<Album>{
        int idx, playCnt;

        public Album(int idx, int playCnt) {
            this.idx = idx;
            this.playCnt = playCnt;
        }

        @Override
        public int compareTo(Album album) {
            if(this.playCnt == album.playCnt) {
                return this.idx - album.idx;
            } else {
                return album.playCnt - this.playCnt;
            }
        }
    }

    public int[] solution(String[] genres, int[] plays) {
        int len = genres.length;
        Map<String, Integer> genreRank = new HashMap<>();
        Map<String, List<Album>> albumRank = new HashMap<>();

        // 데이터 초기화
        for (int i = 0; i < len; i++) {
            genreRank.put(genres[i], genreRank.getOrDefault(genres[i], 0) + plays[i]);
            albumRank.putIfAbsent(genres[i], new ArrayList<>());
            albumRank.get(genres[i]).add(new Album(i, plays[i]));
        }

        // 장르별 총 재생 횟수에 따라 장르 정렬
        List<String> sortedGenres = new ArrayList<>(genreRank.keySet());
        sortedGenres.sort((a, b) -> genreRank.get(b) - genreRank.get(a));

        List<Integer> ans = new ArrayList<>();

        // 각 장르 내에서 앨범 정렬 및 상위 2곡 선택
        for (String genre : sortedGenres) {
            List<Album> genreAlbum = albumRank.get(genre);
            Collections.sort(genreAlbum);
            for (int i = 0; i < Math.min(2, genreAlbum.size()); i++) {
                ans.add(genreAlbum.get(i).idx);
            }
        }

        // 결과를 배열로 반환
        return ans.stream().mapToInt(Integer::intValue).toArray();
    }
}

코드 설명

static class Album implements Comparable<Album> {
    int idx, playCnt;

    public Album(int idx, int playCnt) {
        this.idx = idx;
        this.playCnt = playCnt;
    }

    @Override
    public int compareTo(Album album) {
        if(this.playCnt == album.playCnt) {
            return this.idx - album.idx;
        } else {
            return album.playCnt - this.playCnt;
        }
    }
}

 

  • Album 클래스:
    • 각 앨범(노래)의 인덱스(idx)와 재생 횟수(playCnt)를 나타냅니다.
    • compareTo 메서드는 재생 횟수를 기준으로 내림차순 정렬하며, 재생 횟수가 같으면 인덱스 기준으로 오름차순 정렬합니다.
  • solution 메서드:
    • genreRank 해시맵: 각 장르별 총 재생 횟수를 저장합니다.
    • albumRank 해시맵: 각 장르별로 Album 객체 리스트를 저장합니다.
    • for 루프를 사용해 genreRank와 albumRank를 초기화합니다.
      • 각 노래를 해당 장르의 총 재생 횟수에 추가하고, Album 객체를 장르 리스트에 추가합니다.
    • genreRank의 키(장르)를 재생 횟수에 따라 내림차순으로 정렬하여 sortedGenres 리스트를 만듭니다.
      sortedGenres.sort((a, b) -> genreRank.get(b) - genreRank.get(a));
// 각 장르 내에서 앨범 정렬 및 상위 2곡 선택
for (String genre : sortedGenres) {
    List<Album> genreAlbum = albumRank.get(genre);
    Collections.sort(genreAlbum);
    for (int i = 0; i < Math.min(2, genreAlbum.size()); i++) {
        ans.add(genreAlbum.get(i).idx);
    }
}
  • 장르 내 노래 정렬 및 선택:
    • 각 장르의 노래 리스트(genreAlbum)를 Collections.sort를 통해 정렬합니다.
    • 상위 2개의 노래 인덱스를 결과 리스트 ans에 추가합니다.
  • int[] 타입으로 반환해야하니 ans 리스트를 배열로 변환해 반환합니다.
    return ans.stream().mapToInt(Integer::intValue).toArray();

 

+ Recent posts