CS/Algorism

99클럽 코테 스터디 1일차 TIL: [프로그래머스] 베스트앨범

olsohee 2024. 5. 20. 22:39

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

 

프로그래머스

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

programmers.co.kr

정렬 조건에 주의해야 하며, 그 외로는 해시를 사용하여 단순히 구현만 하면 되는 문제이다. 그런데 이렇게도 생각하고 저렇게도 생각해야 해서 간단한듯 좀 지저분하게 코드를 짠 거 같다.. 좀 더 효율적으로 풀 수 있는 방법이 생각나면 수정해야겠다.

 

그리고 항상 동적으로 배열 길이가 정해질 때, List에 값을 먼저 채운 후 list.size() 만큼의 크기의 배열을 선언하여 리스트 값을 배열로 옮기는 작업을 진행했었다. 그런데 스트림을 통해 더 간단하게 리스트를 배열 형태로 반환하는 방법을 알게 되었다!

import java.util.*;

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        
        Map<String, List<Info>> genreAndPlay = new HashMap<>();
        Map<String, Integer> playSum = new HashMap<>();
        List<Rank> rankList = new ArrayList<>();
        
        for (int i = 0; i < genres.length; i++) {
            List<Info> list = genreAndPlay.getOrDefault(genres[i], new ArrayList<>());
            list.add(new Info(plays[i], i));
            genreAndPlay.put(genres[i], list);
            
            playSum.put(genres[i], playSum.getOrDefault(genres[i], 0) + plays[i]);
        }
        
        // 재생 횟수가 높은 순으로 장르 정렬
        for (String genre : playSum.keySet()) {
            rankList.add(new Rank(genre, playSum.get(genre)));
        }
        Collections.sort(rankList);
        
        // 각 장르 내에서 재생 횟수가 높은 노래 2개 선정
        List<Integer> answer = new ArrayList<>();
        for (Rank rank : rankList) {
            int addCnt = 0;
            Collections.sort(genreAndPlay.get(rank.genre));
            for (Info info : genreAndPlay.get(rank.genre)) {
                if (addCnt >= 2) break;
                answer.add(info.idx);
                addCnt++;
            }
        }
        
        return answer.stream()
            .mapToInt(num -> num)
            .toArray();
    }
    
    class Rank implements Comparable<Rank> {
        
        String genre;
        int playSum;
        
        public Rank(String genre, int playSum) {
            this.genre = genre;
            this.playSum = playSum;
        }
        
        @Override
        public int compareTo (Rank o) {
            return o.playSum - this.playSum;
        }
    }
    
    class Info implements Comparable<Info> {
        
        int cnt;
        int idx;
        
        public Info (int cnt, int idx) {
            this.cnt = cnt;
            this.idx = idx;
        }
        
        @Override
        public int compareTo (Info o) {
            if (o.cnt == this.cnt) {
                return this.idx - o.idx;
            }
            return o.cnt - this.cnt;
        }
    }
}