CodingTEST

[프로그래머스] 베스트앨범 (JAVA)

경걍 2023. 12. 10. 22:55
반응형

프로그래머스 - [Level 3] 베스트앨범

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 분석

 

  • 스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려한다.
  • 베스트앨범의 노래 고유번호 리스트를 반환해라
  • 노래를 수록하는 기준
    → 쉽게 말해 장르별 재생횟수로 정렬, 장르가 같을 경우 많이 재생된 순으로 정렬, 재생 수가 동일할 경우 고유 번호 순으로 정렬
    • 속한 노래가 많이 재생된 장르를 먼저 수록
    • 장르 내에서 많이 재생된 노래를 먼저 수록
    • 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록
  • 장르별 두개씩 모아서 베스트 앨범을 만드므로 해당 장르에서 2등 밑으로는 수록 X

 

  • 얻어지는 입력
    • genres[i]는 고유번호가 i인 노래의 장르입니다. 
    • plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.

 


해결 키 포인트

 

  • 많이 재생된 장르 순위를 구하기 위해 HashMap 사용
    • key: 장르이름 | value: 해당 장르의 재생 횟수
  • Song 클래스 생성
    • 고유번호(index), 재생횟수(playCount), 해당장르재생횟수(genresCount)를 인자로 소유
    • genresCount은 위에 해시맵의 해당장르가 key인 value 값으로 설정
  • Comparable<Song>을 implements 해서 정렬을 편리하게 구현
    • 이러면 Collection.sort에서 해당 방식대로 비교 후 정렬한다.
    • genresCount 먼저 비교 → playCount 비교 → index 비교
    • 리턴 값이 양수면 해당 객체가 앞으로, 음수면 해당 객체가 뒤로 정렬
  • 장르별 2개만 수록하기 위해 정렬 후 최근에 참고한 장르재생횟수와 리스트에 추가한 횟수 비교
    • 장르 재생 횟수가 다르면 리스트에 추가한 횟수 0으로 초기화
    • 리스트에 추가한 횟수가 2이상이면 해당 노래는 수록 안하고 넘어가기 ( continue; )
  • 반환할 리스트는 Arrays.copyOfRange로 리스트에 추가된 횟수만큼만 잘라서 반환
    • 리스트에 추가된 횟수는 리스트에 넣을 때 사용한 index 사용

코드
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        HashMap<String, Integer> counts = new HashMap<>();

         for (int i = 0; i < genres.length; i++) {
            int count = 0;
            if(counts.containsKey(genres[i])) {
                count = counts.get(genres[i]);
            }
            counts.put(genres[i], count+plays[i]);
        }

        ArrayList<Song> songs = new ArrayList<>();
        for (int i = 0; i < genres.length; i++) {
            songs.add(new Song(i, plays[i], counts.get(genres[i])));
        }

        Collections.sort(songs);

        int[] answer = new int[songs.size()];
        int index = 0;
        int genresCount = 0;
        int songCount = 0;
        for (int i = 0; i < songs.size(); i++) {
            Song song = songs.get(i);
            if(genresCount != song.genresCount) {
                songCount = 0;
                genresCount = song.genresCount;
            }
            if(songCount >= 2) {
                continue;
            }
            answer[index] = song.index;
            songCount++;
            index++;
        }


        return Arrays.copyOfRange(answer, 0, index);
    }

    public static class Song implements Comparable<Song> {
        int index;
        int playCount;
        int genresCount;

        public Song(int index, int playCount, int genresCount) {
            this.index = index;
            this.playCount = playCount;
            this.genresCount = genresCount;
        }

        @Override
        public int compareTo(Song s) {
            if (genresCount == s.genresCount) {
                if (playCount == s.playCount)
                    return index - s.index;
                return s.playCount - playCount;
            }
            return s.genresCount - genresCount;
        }
    }
}
반응형