[프로그래머스/java] lv3. 베스트앨범

somyeong·2022년 10월 10일
0

프로그래머스

목록 보기
10/14

문제 링크 - https://school.programmers.co.kr/learn/courses/30/lessons/42579

🌱 문제


🌱 풀이

문제 요약

  • 문제를 요약해보면 다음과 같다.
    1. 장르별로 가장 많이 재생된 노래를 두 곡씩 찾는다.
    2. 이때, 장르는 속한 노래가 가장 많이 재생된 순서이다.
    3. 장르 내에서는 재생 횟수가 많은 노래부터 찾는다.
    4. 장르 내에서 재생횟수가 같은 노래가 있다면 인덱스가 낮은것을 먼저 고르자.
    5. 장르 내에 1곡 뿐이라면 그 곡만 선택한다.

1. 장르별 재생 횟수 기준 오름차순을 구하자

  • HashMap<String, Integer> map 자료형에 장르별로 재생횟수를 더해서 오름차순으로 정렬한 값을 반환하였다. 이때List<Map.Entry<String,Integer>> 자료형에 담아서 정렬하였다
HashMap<String, Integer> map = new HashMap<String,Integer>();
        for(int i=0; i<genres.length; i++){
            if(map.containsKey(genres[i])) // map에 해당 장르(key)가 있으면 재생횟수 누적.
                map.put(genres[i],map.get(genres[i])+plays[i]);
            else
                map.put(genres[i],plays[i]); // map에 해당 장르(key)가 없으면 그대로 삽입 
        }
        
        List<Map.Entry<String,Integer>> entryList = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
        
        entryList.sort((o1,o2)->o2.getValue()-o1.getValue()); // 재생횟수 기준 내림차순으로 정렬
  • 결과적으로 List<Map.Entry<String,Integer>> 형태인 entryList에 재생횟수 기준 오름차순으로 (장르이름, 재생횟수) entry 가 겨있게 된다.

2. 장르 내에서 재생횟수 기준 내림차순으로 2곡 선정하기

(재생횟수 같다면 인덱스 낮은 순, 장르내에 1곡뿐이면 그 곡만 선택)

  • 앞에서 구한 entryList를 돌면서 각 장르마다 해당하는 곡(Music 자료형)을 새로운 ArrayList<Music> list에 담는다.
  • 그리고 정렬한다. Music 클래스를 정의할 때, 재생횟수 내림차순으로 정렬하되, 같으면 고유번호 오름차순 정렬 하도록 정렬조건을 정의 해 놓았다.
 int cnt=0; //cnt:  정답배열인 answer[]의 사이즈 구하기  
        ArrayList<Integer> answers= new ArrayList<Integer>();
        for(Map.Entry<String,Integer> entry : entryList){
            String curGenre = entry.getKey();
            ArrayList<Music> list = new ArrayList<Music>();
            for(int i=0; i<genres.length; i++){
                if(genres[i].equals(curGenre))
                    list.add(new Music(i,plays[i]));
            }
            Collections.sort(list); // Music class에 정의한 정렬 조건에 따라서 정렬 (재생횟수 내림차순, 인덱스 오름차순)

3. 베스트 앨범에 해당하는 노래의 고유번호 answer배열에 담기

  • 정렬해준 리스트에서 앞에서 2개가 각각 베스트 앨범이 된다.
  • 리스트 크기가 1이면 그 1개만 담으면 된다.
  • answer배열의 크기가 정해지지 않아서 우선 ArrayList<Integer> answers에 정답에 해당하는 노래 번호들을 담아 놓고, answers의 크기만큼 answer배열의 크기를 정해준 후 옮겨 담았다.
int cnt=0; //cnt:  정답배열인 answer[]의 사이즈 구하기  
if(list.size()>1){ // 장르에 속한곡이 2개 이상이면 
                answers.add(list.get(0).index);
                answers.add(list.get(1).index);                
                cnt+=2;
            }else if(list.size()==1){
                answers.add(list.get(0).index);
                cnt+=1;
            }  
            
        }
        
        //ArrayList에 담은 정답들 int[]배열에 옮겨주기 
        int[] answer= new int[cnt];
        for(int i=0; i<cnt; i++){
                answer[i]=answers.get(i);
        }
        return answer;

🌱 코드

import java.util.*;

class Music implements Comparable<Music>{
    int index;
    int plays;
    public Music(int index, int plays){
        this.index=index;
        this.plays=plays;
    }
    
    @Override
    public int compareTo(Music m){ // 재생횟수 내림차순으로 정렬하되, 같으면 고유번호 오름차순 정렬
        if(this.plays==m.plays)
            return this.index-m.index; // 고유번호 오름차순 
        
        return m.plays-this.plays; //재생횟수 내림차순 
    }
    
    
}

class Solution {
    public int[] solution(String[] genres, int[] plays) {
    
        HashMap<String, Integer> map = new HashMap<String,Integer>();
        for(int i=0; i<genres.length; i++){
            if(map.containsKey(genres[i]))
                map.put(genres[i],map.get(genres[i])+plays[i]);
            else
                map.put(genres[i],plays[i]);
        }
        
        List<Map.Entry<String,Integer>> entryList = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
        
        entryList.sort((o1,o2)->o2.getValue()-o1.getValue());
        
        // for(Map.Entry<String,Integer>entry: entryList){
        //     System.out.println("key: "+entry.getKey()+", value: "+entry.getValue());
        // }
        
        int cnt=0; //cnt:  정답배열인 answer[]의 사이즈 구하기  
        ArrayList<Integer> answers= new ArrayList<Integer>();
        for(Map.Entry<String,Integer> entry : entryList){
            String curGenre = entry.getKey();
            ArrayList<Music> list = new ArrayList<Music>();
            for(int i=0; i<genres.length; i++){
                if(genres[i].equals(curGenre))
                    list.add(new Music(i,plays[i]));
            }
            Collections.sort(list); // Music class에 정의한 정렬 조건에 따라서 정렬 (재생횟수 내림차순, 인덱스 오름차순)
            if(list.size()>1){ // 장르에 속한곡이 2개 이상이면 
                answers.add(list.get(0).index);
                answers.add(list.get(1).index);                
                cnt+=2;
            }else if(list.size()==1){
                answers.add(list.get(0).index);
                cnt+=1;
            }  
            
        }
        
        //ArrayList에 담은 정답들 int[]배열에 옮겨주기 
        int[] answer= new int[cnt];
        for(int i=0; i<cnt; i++){
                answer[i]=answers.get(i);
        }
        return answer;
    }
}
profile
공부한 내용 잊어버리지 않게 기록하는 공간!

0개의 댓글