베스트앨범

개발새발log·2023년 5월 5일
0

Programmers

목록 보기
34/35

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42579?language=java

접근 방식은 어렵지 않은데 비해, Java로 구현해내는 과정이 더 까다로웠던 문제 .. 🫠🫠

풀이

장르와 일대일 매핑된 음악 리스트들을 담은 맵을 활용했다.

해당 장르에 음악 id와 재생 횟수를 담아서 초기화를 완료한 뒤,

총 재생 횟수를 기준으로 장르 리스트를 소팅하기 위해 스트림을 활용해 총 재생 횟수 기준으로 정렬했다.

List<String> keys = new ArrayList<>(datas.keySet());
keys.sort((g1, g2) -> datas.get(g2).stream().mapToInt(Music::getPlayCnt).sum() - datas.get(g1).stream().mapToInt(Music::getPlayCnt).sum());

소팅된 장르 리스트를 돌면서 Music에서 만들어놓은 정렬 기준에 따라 음악 리스트를 정렬한 뒤, 최대 2개씩 뽑아서 정답에 담았다

// Music
public int compareTo(Music m){
    if (this.playCnt - m.playCnt == 0) 
        return this.id - m.id;
    return m.playCnt - this.playCnt;
}

고난 기록 (?

Genre 클래스 따로, Music 클래스 따로 둬서 Genre를 리스트에 저장했다가 장르명에 해당하는 객체를 가져오고 집어넣고 하는데서 하도 꼬여서 그제서야 '아 이건 맵을 활용하는 게 정신건강에 이롭구나'를 깨닫고 방향 튼 1인 .. ◠ ̫◠

코드 - Java

import java.util.*;

class Music implements Comparable<Music>{
    int id;
    int playCnt;
    
    Music(int id, int playCnt) { this.id = id; this.playCnt = playCnt; }
    
    // 재생 횟수 기준 내림차순, 고유번호 기준 오름차순
    public int compareTo(Music m){
        if (this.playCnt - m.playCnt == 0) 
            return this.id - m.id;
        return m.playCnt - this.playCnt;
    }
    
    public String toString(){ return "" + id; }
    
    public int getPlayCnt() { return playCnt; }
}

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        Map<String, List<Music>> datas = new HashMap<>();
        
        // 장르/음악 담기
        for(int i = 0; i < plays.length; i++){
            List<Music> mList = datas.getOrDefault(genres[i], new ArrayList<Music>());
            mList.add(new Music(i, plays[i]));
            
            datas.put(genres[i], mList);
        }
        
        // List<Music>의 총 playCnt 기준 장르 정렬
        List<String> keys = new ArrayList<>(datas.keySet());
        keys.sort((g1, g2) 
                    -> datas.get(g2).stream().mapToInt(Music::getPlayCnt).sum() - datas.get(g1).stream().mapToInt(Music::getPlayCnt).sum());
        
        // 장르별 조건 만족하는 두곡씩 뽑기
        List<Integer> numbers = new ArrayList<>();
        for (String g : keys){
            List<Music> curM = datas.get(g);
            Collections.sort(curM);
            
            numbers.add(curM.get(0).id);
            if (curM.size() >= 2) numbers.add(curM.get(1).id);
        }
        
        return numbers.stream()
            .mapToInt(Integer::intValue)
            .toArray();
    }
}

코드 - Python

파이썬에 깊게 감사하는 마음을 가지게 됐다 ◠ ̫◠

from collections import defaultdict

def solution(genres, plays):
    songs = defaultdict(list) # 음악 장르, 재생 횟수
    total_list = [] # 합 저장
    
    ids = [i for i in range(len(genres))]
    for id, genre, play in zip(ids, genres, plays):
        songs[genre].append((id, play))
    for k, v in songs.items():
        v.sort(key=lambda x: x[1], reverse=True)
        total = 0
        for vv in v: total+=vv[1]
        total_list.append([k, total])
    
    total_list.sort(key= lambda x : x[1], reverse=True)
    
    ans = []
    for g, _ in total_list:
        ans.append(songs[g][0][0])
        if len(songs[g]) > 1:
            ans.append(songs[g][1][0])
    
    return ans
profile
⚠️ 주인장의 머릿속을 닮아 두서 없음 주의 ⚠️

0개의 댓글