Level3 - 베스트앨범
문제
문제 설명
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.
- 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
- 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
- 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.
제한 사항
- genres[i]는 고유번호가 i인 노래의 장르입니다.
- plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.
- genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다.
- 장르 종류는 100개 미만입니다.
- 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
- 모든 장르는 재생된 횟수가 다릅니다.
입출력 예
genres | plays | return |
["classic", "pop", "classic", "classic", "pop"] | [500, 600, 150, 800, 2500] | [4, 1, 3, 0] |
입출력 예 설명
classic 장르는 1,450회 재생되었으며, classic 노래는 다음과 같습니다.
- 고유 번호 3: 800회 재생
- 고유 번호 0: 500회 재생
- 고유 번호 2: 150회 재생
pop 장르는 3,100회 재생되었으며, pop 노래는 다음과 같습니다.
- 고유 번호 4: 2,500회 재생
- 고유 번호 1: 600회 재생
따라서 pop 장르의 [4, 1]번 노래를 먼저, classic 장르의 [3, 0]번 노래를 그다음에 수록합니다.
- 장르 별로 가장 많이 재생된 노래를 최대 두 개까지 모아 베스트 앨범을 출시하므로 2번 노래는 수록되지 않습니다.
※ 공지 - 2019년 2월 28일 테스트케이스가 추가되었습니다.
나의 풀이
풀이 접근 과정
문제에서 주어진 조건대로 차근차근 풀어갔다.
장르별로 개수와 수록곡을 구분해야하니까 Map을 써야한다는 생각이 들었다.
map에서 play수를 정렬해야하니까 value에 값을 넣어야 했다.
그러면서 수록될 두 곡을 한번에 넣어야하니까 value 값에 총 재생수와 수록곡을 넣어야 했다.
Map[장르] = Pair<총 재생수, 수록될 두 곡>
최종 풀이
1. 각 장르별 총 재생수와 수록곡을 저장할 MutableMap()을 생성한다.
2. genres와 plays를 동시에 반복문을 돈다
- 해당 장르가 map에 존재하지 않으면
- 현재 장르의 총 재생수를 현재 plays 수로 초기화한다.
- 첫번째 수록곡은 현재 재생수로, 두번째 수록곡은 재생수를 0으로 초기화한다.
- 해당 장르가 map에 존재하면
- 현재 장르의 총 재생수를 업데이트한다.
- 현재 plays의 값이 첫번째 수록곡의 재생수보다 많으면 처음으로 수록한다.
- 현재 plays의 값이 두번째 수록곡의 재생수보다 많으면 두번곡과 바꿔 수록한다.
3. map을 array로 변환한 다음 총 재생수가 많은 순으로 정렬한다.
4. 수록곡을 list에 담아 리턴한다.
- 두번째 수록곡의 재생수가 0이면 재생된 곡은 한 곡이므로 한 곡만 수록한다.
class Solution {
fun solution(genres: Array<String>, plays: IntArray): IntArray {
val answer = arrayListOf<Int>()
val songs: MutableMap<String, Pair<Int, Array<Pair<Int, Int>>>> = mutableMapOf()
for (i in genres.indices) {
val key = genres[i]
val value = plays[i]
if (songs.containsKey(key)) {
val sum = songs[key]!!.first
val firstMax = songs[key]!!.second[0]
val secondMax = songs[key]!!.second[1]
if (value > firstMax.second) {
songs[key] = Pair(sum+value, arrayOf(Pair(i, value), firstMax))
} else if (value > secondMax.second) {
songs[key] = Pair(sum+value, arrayOf(firstMax, Pair(i, value)))
} else {
songs[key] = Pair(sum+value, arrayOf(firstMax, secondMax))
}
} else {
songs[key] = Pair(value, arrayOf(Pair(i, value), Pair(0,0)))
}
}
val array: Array<Pair<Int, Array<Pair<Int, Int>>>> =
songs.keys.map {
Pair(songs[it]!!.first, songs[it]!!.second) }
.sortedByDescending { value -> value.first }
.toTypedArray()
array.forEach {
if (it.second[1].second == 0) {
answer.add(it.second[0].first)
} else {
answer.add(it.second[0].first)
answer.add(it.second[1].first)
}
}
return answer.toIntArray()
}
}
테스트 1 〉 | 통과 (24.33ms, 63.8MB) |
테스트 2 〉 | 통과 (18.42ms, 63.5MB) |
테스트 3 〉 | 통과 (9.67ms, 61.2MB) |
테스트 4 〉 | 통과 (12.28ms, 59.8MB) |
테스트 5 〉 | 통과 (20.97ms, 64.3MB) |
테스트 6 〉 | 통과 (23.74ms, 63.8MB) |
테스트 7 〉 | 통과 (28.34ms, 63.3MB) |
테스트 8 〉 | 통과 (17.90ms, 63.3MB) |
테스트 9 〉 | 통과 (22.11ms, 63.7MB) |
테스트 10 〉 | 통과 (18.10ms, 63.8MB) |
테스트 11 〉 | 통과 (18.85ms, 64.1MB) |
테스트 12 〉 | 통과 (17.01ms, 63.4MB) |
테스트 13 〉 | 통과 (17.16ms, 64.6MB) |
테스트 14 〉 | 통과 (18.55ms, 63.8MB) |
테스트 15 〉 | 통과 (16.44ms, 63.4MB) |
다른 사람의 풀이
풀이 1
1. genres를 그룹핑한다.
- LinkedHashMap(장르, ArrayList(번호))
2. 그루핑한 genres를 리스트로 변환한다.
- Arrray<Pair(장르,ArrayList(번호))>
3. Plays에서 array에 second(ArrayList(번호))) 번호에 해당하는 값들을 sum하여 sum을 기준으로 리스트를 내림차순 정렬한다.
4. Plays에서 array에 second(ArrayList(번호))) 번호에 해당하는 값들을 내림차순 정렬하여 2개를 뽑아 intArray로 만들고 리턴한다.
class Solution {
fun solution(genres: Array<String>, plays: IntArray): IntArray {
return genres.indices.groupBy { genres[it] }
.toList()
.sortedByDescending { it.second.sumBy { plays[it] } }
.map { it.second.sortedByDescending { plays[it] }.take(2) }
.flatten()
.toIntArray()
}
}
Comment
제한조건에 맞춰 map 구조를 설정했더니 금방 풀 수 있는 문제였다.
그리고 다른 사람의 풀이를 보고 좌절했다.
kotlin의 스코프 함수 만으로도 간단하게 해결할 수 있는 문제였다....
kotlin은 이렇게 쓰는 거구나.. 나는 여전히 kotlin을 java처럼 쓰고 있다......
'프로그래머스 > Kotlin | Level3' 카테고리의 다른 글
[프로그래머스/Kotlin]Level3 - 가장 먼 노드 (1) | 2023.05.09 |
---|---|
[프로그래머스/Kotlin]Level3 - 순위 (0) | 2023.03.31 |
[프로그래머스/Kotlin]Level3 - 연속 펄스 부분 수열의 합 (0) | 2023.03.12 |
[프로그래머스/Kotlin]Level3 - 기둥과 보 설치 (0) | 2023.03.06 |
[프로그래머스/Kotlin]Level3 - 징검다리 건너기 (0) | 2023.02.26 |