문제분석:
문제 목표: 장르마다 최대 2곡씩 모아 베스트앨범을 만든다.
규칙1: 가장 많이 플레이된 장르를 우선한다.
규칙2: 장르내에서 가장 많이플레이된 노래를 우선한다.
규칙3: 플레이가 같으면 고유번호가 작은것을 우선한다.
풀이는 다양하게 존재한다.
Map을 2개 작성하여, <장르,플레이수> , <장르, 곡정보> 를 넣어서 풀어도된다.
근데 필자는 Map 1개로도 이 문제를 풀 수 있을것 같은것이다.
우선 객체 클래스 2개를 만들었다.
장르 클래스 하나 만들었다.
장르는 장르 이름과, 노래들의 리스트를 수록한다.
기본 생성자로 이름과 노래를 입력받아 자료들을 저장한다.
장르 안에 있던 Song 노래의 대한 객체이다.
노래는 각각 고유아이디와 플레이횟수를 가진다.
고유아이디는 노래가 새로 하나가 생설될때마다, Static 변수로 선언된 노래 고유아이디가 1씩증가한다.
밑준비는 모두 완료가 되었으니 본격적으로 풀어보자.
우선 Map은 <장르, 총 플레이횟수>로 선언한다.
이렇게 선언해두고 사용한다면,
1차적으로 총플레이 횟수로 정렬하여 장르별로 정렬하고
2차적으로 장르속에 있는 노래들을 2차정렬해서 사용하면 된다.
데이터를 집어넣는 로직이다.
노래와 장르 객체를 하나씩 만들어둔다. 새로 만들때는 map을 추가하지만,
장르의 이름이 같으면 새로 map을 추가하지않고 그 장르속에다 노래를 추가해야한다.
장르의 이름이 같을경우 실행되는 메소드다.
장르의 이름이같을경우에, 같은 장르에 노래를 하나추가하고, 총 플레이횟수 역시 증가시킨다.
단, Map에 들어간 총 플레이횟수는 Integer로 Wrapping되어있기에,
언박싱 -> 산술 -> 박싱 과정을 거쳐야한다.
데이터를 모두 집어넣엇으면 남은건 정렬 과제만 남았다.
우선 규칙 1에 따라 총플레이횟수에따라 정렬을 해준다.
기존 HashMap은 정렬을 지원하지 않기에, 따로 리스트를 뽑아서 정렬을 진행했다.
본래 자동정렬기능을 탑재한 TreeMap을 사용하려했지만...
어째선지 사용하려고하면 지금까지 작성햇던 로직들과 충돌현상이 벌어진다..
이 버그를 해결하기위한 아이디어가 당장 떠오르지않기에 차선책으로 리스트로 뽑았다.
규칙 2번 과 3번
노래들을 정렬해준다.
그냥 단순 정렬이라면 람다를 사용했겟지만, 규칙 3번이 있어서 Comparator를 하나 생성해서 재정의(오버라이딩) 했다.
또한 전제가, 장르마다 최대 2곡이니 이 규칙도 놓치지말자.
문제풀이:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
import java.util.*;
class Solution {
Map<Gnere,Integer> map;
static int song_id=0;
public List<Integer> solution(String[] genres, int[] plays) {
List<Integer> result = new ArrayList<>();
map = new HashMap<>();
for(int i=0; i<genres.length;i++){
Song s = new Song(plays[i]);
Gnere temp =new Gnere(genres[i],s);
//장르가 겹칠때
if(isDistinct(temp,plays[i])){
continue;
}
//새로 만들때
map.put(temp,plays[i]);
}
//리스트로 뽑아서 장르 정렬..
List<Gnere> keySetList = new ArrayList<>(map.keySet());
Collections.sort(keySetList, (o1, o2) -> (map.get(o2).compareTo(map.get(o1))));
for(Gnere key : keySetList) {
List<Song> s_list =key.getSongs();
//노래 정렬
Collections.sort(s_list,new Comparator<Song>(){
public int compare (Song s1, Song s2){
if(s1.getCount()==s2.getCount()){
return Integer.compare(s1.getId(),s2.getId());
}
return Integer.compare(s2.getCount(),s1.getCount());
}
});
int max_count=2;
for(Song s : s_list){
if(max_count==0){
break;
}
result.add(s.getId());
max_count--;
}
}
return result;
}
public boolean isDistinct(Gnere g,int count) {
for (Gnere s : map.keySet()) {
if(s.getName().equals(g.getName())){
s.addSong(g.getSongs().get(0));
//Integer 산술연산
int p_count=map.get(s).intValue();
p_count+=count;
Integer c =(Integer)p_count;
map.replace(s,c);
return true;
}
}
return false;
}
static class Gnere{
private String name;
private List<Song> songs = new ArrayList<>();
public Gnere(String name,Song song){
this.name =name;
addSong(song);
}
public String getName(){
return name;
}
public List<Song> getSongs(){
return songs;
}
public void addSong(Song s){
songs.add(s);
}
}
static class Song{
private int id;
private int count;
public Song(int count){
id=song_id++;
this.count= count;
}
public int getId(){
return id;
}
public int getCount(){
return count;
}
}
}
|
cs |
'알고리즘 > 프로그래머스 Level3' 카테고리의 다른 글
[프로그래머스,Java] Level3: 선입 선출 스케줄링 (0) | 2022.07.30 |
---|---|
[프로그래머스,JAVA] Level3: 입국심사 (0) | 2022.07.29 |
[프로그래머스,자바] Level3: 추석 트래픽 (0) | 2022.02.13 |
[프로그래머스,Java] Levle3: 위클리챌린지 11주차[아이템 줍기] (1) | 2021.10.19 |
[프로그래머스,자바] Level3: 다단계 칫솔 판매 (0) | 2021.09.28 |