Algorithm/Hash
[프로그래머스] 베스트앨범(해시) - java
Dev_Green
2022. 12. 6. 17:32
https://school.programmers.co.kr/learn/courses/30/lessons/42579
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
풀이
이 문제에서 유의해야할 조건은 아래와 같다.
- 장르별 최대 두 곡까지만 수록한다.
- 장르별 재생횟수의 합이 가장 큰 장르부터 수록한다.
- 장르 내에서는 재생횟수가 가장 큰 곡부터 수록한다.
- 장르 내에서 재생횟수가 같을 경우 고유번호가 낮은 순서대로 수록한다.
이에 따라 문제는 다음과 같은 순서로 풀어나갔다.
- 장르별 재생횟수 총합 구한다.
- 해시맵 생성
- 장르 간 우선순위를 정립한다.
- 해시맵의 value값을 기준으로 내림차순 정렬
- 각 장르를 돌면서 장르 내 수록곡 간 우선순위 정립한다.
- 경우에 따라 수록곡이 하나밖에 없는 경우가 있음을 유의하여 처리
코드
class Solution {
public int[] solution(String[] genres, int[] plays) {
HashMap<String, Integer> map = new HashMap<>();
// 장르별 총 재생 횟수를 나타내는 map 생성
for (int i = 0; i < genres.length; i++) {
map.put(genres[i], map.getOrDefault(genres[i], 0) + plays[i]);
}
// map에서 키값(장르)만 추출하여 genre라는 리스트에 입력
ArrayList<String> genre = new ArrayList<>();
for (String key : map.keySet()) {
genre.add(key);
}
Collections.sort(genre, (o1, o2) -> map.get(o2) - map.get(o1)); // value 값을 기준으로 내림차순 정렬
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < genre.size(); i++) {
String g = genre.get(i);
// 해당 장르(g)의 음악 중에서 play 값이 첫번째로 큰 인덱스를 찾는다
int max = 0;
int firstIdx = -1;
for (int j = 0; j < genres.length; j++) {
if (g.equals(genres[j]) && plays[j] > max) {
max = plays[j];
firstIdx = j;
}
}
// play 값이 두번째로 큰 인덱스를 찾는다
max = 0;
int secondIdx = -1;
for (int j = 0; j < genres.length; j++) {
if (g.equals(genres[j]) && plays[j] > max && j != firstIdx) {
max = plays[j];
secondIdx = j;
}
}
list.add(firstIdx);
if (secondIdx >= 0) { // secondIdx 값이 갱신되지 않았다면 두번째 값이 존재하지 않는 것
list.add(secondIdx);
}
}
int[] answer = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
}