728x90
반응형
문제 출처 : 링크
장르와 노래는 해시 테이블을 직접 구현해 관리하고, 베스트앨범에 넣을 인덱스는 퀵소트를 만들어 뽑아냈다.
라이브러리 안쓰고 푸는 연습에 매우매우 좋은 문제 같다.
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
public class 베스트앨범 {
static final int hash_size = 1000;
static final int hash_len = 40;
static final int hash_val = 257;
static int[][] hash_table = new int[hash_size][hash_len];
static int[] cnt = new int[hash_size];
static int[] plays_m;
static String[] genres_m;
static class Music {
int playtime;
int idx;
Music(int playtime, int idx) {
this.playtime = playtime;
this.idx = idx;
}
public int getPlaytime() {
return playtime;
}
public void setPlaytime(int playtime) {
this.playtime = playtime;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
}
public static int getHashKey(String str) {
int key = 0;
for (int i = 0; i < str.length(); i++) {
key = (key*hash_val) + str.charAt(i);
}
if(key < 0) key = -key;
return key % hash_size;
}
public static boolean isEquals(String origin, String compare) {
if(origin.length() != compare.length()) return false;
for (int i = 0; i < origin.length(); i++) {
if(origin.charAt(i) != compare.charAt(i)) return false;
}
return true;
}
public static int[] solution(String[] genres, int[] plays) {
int[] answer = {};
genres_m = new String[genres.length];
plays_m = new int[plays.length];
int[] result = new int[genres.length];
int result_idx = 0;
//테이블에 index를 저장
for (int i = 0; i < genres.length; i++) {
String genre = genres[i];
int play = plays[i];
int index = i;
int key = getHashKey(genre);
if(cnt[key] == 0) { // 처음 들어온 장르
hash_table[key][cnt[key]++] = index;
plays_m[index] = play;
genres_m[index] = genre;
}
else { // 들어온 적이 있거나, 충돌된 경우
boolean chk = false;
for (int j = 0; j < cnt[key]; j++) {
int idx = hash_table[key][j];
if(isEquals(genres_m[idx], genre)) { // 들어온적 있는 경우
hash_table[key][cnt[key]++] = index;
plays_m[index] = play;
genres_m[index] = genre;
break;
}
else { // 들어온 적 없는 경우
chk = true;
break;
}
}
if(chk) {
int temp = key+1;
while(true) {
if(cnt[temp] == 0) {
break;
}
else temp++;
}
hash_table[temp][cnt[temp]++] = index;
plays_m[index] = play;
genres_m[index] = genre;
}
}
}
// genre 별로 정렬해야함
// 1. 속한 노래가 많은 재생한 장르를 찾아야 함
int genreCnt = 0;
int tempIdx = 0;
int[] cntIdx = new int[cnt.length];
for (int i = 0; i < cnt.length; i++) {
if(cnt[i] != 0) {
genreCnt++;
cntIdx[tempIdx++] = i;
}
}
// cntIdx에는 cnt에 key가 저장된 해당 인덱스를 저장해둠
Music[] music1 = new Music[genreCnt];
String[] genresIdx = new String[genreCnt];
for (int i = 0; i < music1.length; i++) {
int key = cntIdx[i];
int sumTime = 0;
for (int j = 0; j < cnt[key]; j++) {
sumTime += plays_m[hash_table[key][j]];
}
String tempStr = genres_m[hash_table[key][0]];
music1[i] = new Music(sumTime, i);
genresIdx[i] = tempStr;
}
quickSort(music1, 0, music1.length-1);
// 많이 저장된 장르부터 정렬된 배열이 완성됨 (sort_cnt)
for (int i = 0; i < music1.length; i++) {
String prio_genre = genresIdx[music1[i].idx];
// 우선 순위 장르의 string을 얻었음. 이 중에 재생 수가 가장 많고, 고유번호가 낮은 2개 뽑기
// 2개가 없으면 1개만 뽑기
int[] genre_idx_list = new int[genres_m.length];
int gidx = 0;
for (int j = 0; j < genres_m.length; j++) {
if(isEquals(prio_genre, genres_m[j])) { // 장르가 일치하는 index
genre_idx_list[gidx++] = j;
}
}
if(gidx == 0) break;
Music[] music = new Music[gidx];
for (int j = 0; j < music.length; j++) {
music[j] = new Music(plays_m[genre_idx_list[j]], genre_idx_list[j]);
}
if(music.length == 1) { // 장르가 한곡이면 걍 뽑으면 됨
result[result_idx++] = music[0].idx;
}
else {
//재생수가 높은 순으로 정렬됨 (2개만 뽑기)
quickSort(music, 0, music.length-1);
for (int j = 0; j < 2; j++) {
Music tempMusic = music[j];
result[result_idx++] = tempMusic.idx;
}
}
}
answer = new int[result_idx];
for (int i = 0; i < answer.length; i++) {
answer[i] = result[i];
}
return answer;
}
public static void quickSort(Music[] arr, int start, int end) {
if(start >= end) return;
if(start < end) {
int i = start-1;
int j = end+1;
Music pivot = arr[(start+end)/2];
while(true) {
while(arr[++i].playtime > pivot.playtime ||
((arr[i].playtime == pivot.playtime) &&
(arr[i].idx < pivot.idx))
) {}
while(arr[--j].playtime < pivot.playtime ||
((arr[j].playtime == pivot.playtime) &&
(arr[j].idx > pivot.idx))
) {}
if(i >= j) break;
Music temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
quickSort(arr, start, i-1);
quickSort(arr, j+1, end);
}
}
public static void main(String[] args) {
String[] genres = {"classic", "pop", "classic", "classic", "pop"};
int[] plays = {500,600,150,800,2500};
}
}
|
cs |
728x90
반응형
'Algorithm' 카테고리의 다른 글
[Algorithm] 카페 주문처리 시스템 (0) | 2021.03.07 |
---|---|
삼성 소프트웨어 역량테스트 PRO등급 준비 (3) | 2020.08.10 |
[알고리즘] 배열 회전 프로그램 (0) | 2018.11.12 |
[삼성 SDS 알고리즘 사전테스트] 순환공간 (0) | 2018.07.26 |
[삼성 SDS 알고리즘 사전테스트] 마지막 생존자 (0) | 2018.07.26 |