Algorithm/Hash

[프로그래머스] 베스트앨범(해시) - java

Dev_Green 2022. 12. 6. 17:32

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

이 문제에서 유의해야할 조건은 아래와 같다.

  • 장르별 최대 두 곡까지만 수록한다.
  • 장르별 재생횟수의 합이 가장 큰 장르부터 수록한다.
  • 장르 내에서는 재생횟수가 가장 큰 곡부터 수록한다.
  • 장르 내에서 재생횟수가 같을 경우 고유번호가 낮은 순서대로 수록한다.

 

이에 따라 문제는 다음과 같은 순서로 풀어나갔다.

  1. 장르별 재생횟수 총합 구한다.
    • 해시맵 생성
  2. 장르 간 우선순위를 정립한다.
    • 해시맵의 value값을 기준으로 내림차순 정렬
  3. 각 장르를 돌면서 장르 내 수록곡 간 우선순위 정립한다.
    • 경우에 따라 수록곡이 하나밖에 없는 경우가 있음을 유의하여 처리

 

코드

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;
    }
}