프로그래머스

프로그래머스_베스트앨범_자바

o늘do 2020. 6. 3. 01:05

 

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

 

코딩테스트 연습 - 베스트앨범

스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가 ��

programmers.co.kr

다음 조건을 보자

  1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
  2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
  3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.

노래가 다음과 같은 정보를( 고유번호 : id, 재생횟수 : play, 장르 : genre) 를 갖는다고하면

조건에 맞게 정렬 하기위해서는

1순위는 많이 재생된 장르 

2순위는 장르 내에서 많이 재생된 노래 

3순위는 재생횟수가 같다면 같은 노래 중에서 고유번호(배열의 index)가 낮은 노래 먼저

 

노래정보를 담는 클래스를 생성하여 위 2, 3 순위에 대한 정렬 기준을 만들어준다.

class Song implements Comparable<Song>{
	int id;
	int play;
	String genre;
	
	public Song(int id, int play, String genre) {
		this.id = id;
		this.play = play;
		this.genre = genre;
	}
    
	public int compareTo(Song o) {
    // 재생횟수가 같다면 고유번호가 낮은거 먼저 !
		if(this.play == o.play) return this.id - o.id; 
   // 재생횟수가 같지 않다면 재생횟수가 많은거 먼저!
		else return o.play - this.play;
	}

1순위는 가장 많이 재생된 장르에 속한곡이 먼저 오도록 정렬해야한다. 

이때 해쉬를 이용한다.

해쉬<장르이름, 총재생횟수>  => 다음과같은 해쉬를 만들어줘서 각장르의 총재생횟수를 저장해둔다.

 

Song 객체들을 담는 LinkedList 를 생성한다.

Song 의 장르가 다르다면 위에 저장한 해쉬를 이용하여 더 많이 재생된 장르가 앞으로 오도록!

Song 의 장르가 같다면 Song에서 정의했던 정렬기준대로 2,3 순위에 해당하는 정렬를 해준다.

 

        Collections.sort(songList, new Comparator<Song>() {

			@Override
			public int compare(Song o1, Song o2) {
            // 장르가 같다면 원래 기준대로
				if(o1.genre.equals(o2.genre)) {
					return o1.compareTo(o2);
				}else {
                // 장르가 다르다면 총재생횟수가 큰게 먼저 오도록
					return genreMap.get(o2.genre) - genreMap.get(o1.genre);
				}
				
			}
			
		});

 

 

 

다음은 전체 코드이다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
class Solution {
    	static LinkedList<Song> songList;
	static LinkedList<Integer> AlbumId;
	static HashMap<String, Integer> genreMap;
	static HashMap<String, Integer> albumMap;
	
    public int[] solution(String[] genres, int[] plays) {
       
        
        songList = new LinkedList<Song>();
        AlbumId = new LinkedList<Integer>();
        genreMap = new HashMap<String, Integer>();
        albumMap = new HashMap<String, Integer>();
        
        for(int i = 0; i < plays.length; i++) {
        	int id = i;
        	int play = plays[i];
        	String genre = genres[i];
        	
        	songList.add(new Song(id, play, genre));
        	
        	if(!genreMap.containsKey(genre)) {
        		genreMap.put(genre, play);
        	}else {
        		genreMap.put(genre, genreMap.get(genre) + play);
        	}
        	
        }
        
         
        Collections.sort(songList, new Comparator<Song>() {

			@Override
			public int compare(Song o1, Song o2) {
				if(o1.genre.equals(o2.genre)) {
					return o1.compareTo(o2);
				}else {
					return genreMap.get(o2.genre) - genreMap.get(o1.genre);
				}
				
			}
			
		});
        
        
        for(Song song : songList){
            if(!albumMap.containsKey(song.genre)){
                albumMap.put(song.genre, 1);
                AlbumId.add(song.id);
            } else {
                int genreCnt = albumMap.get(song.genre);
                
                if(genreCnt >= 2) continue;
                else {
                    albumMap.put(song.genre, genreCnt + 1);
                    AlbumId.add(song.id);
                }
            }
        }
        
        int[] answer = new int[AlbumId.size()];
        for(int i = 0 ; i < answer.length ; ++i){
            answer[i] = AlbumId.get(i);
        }
        
        return answer;
    }
}


class Song implements Comparable<Song>{
	int id;
	int play;
	String genre;
	
	public Song(int id, int play, String genre) {
		this.id = id;
		this.play = play;
		this.genre = genre;
	}
	public int compareTo(Song o) {
		if(this.play == o.play) return this.id - o.id; 
		else return o.play - this.play;
	}
	
	
}