본문 바로가기

Algorithm/Programmers

[해시] 베스트앨범 - Java

문제 바로가기

 

코딩테스트 연습 - 베스트앨범

스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가

programmers.co.kr

해시를 쓰는 문제입니다. 문제 유형에 아예 해시라고 돼있어서 좀 아쉽네여 ^;^

import java.util.*;

class Solution {
	public Integer[] solution(String[] genres, int[] plays) {
		List<Integer> answer = new ArrayList<>();
		Map<String, Integer> sum = new TreeMap<>();
		Map<String, Map<Integer, Integer>> list = new HashMap<>();

		for (int i = 0; i < genres.length; i++) {
			// 장르 별 플레이 수
			if (sum.containsKey(genres[i]) == false) sum.put(genres[i], plays[i]);
			else sum.put(genres[i], sum.get(genres[i]) + plays[i]);

			// 노래 별 플레이 수
			if (list.containsKey(genres[i]) == false) {
				list.put(genres[i], new HashMap<>());
			}
            list.get(genres[i]).put(i, plays[i]);
		}

		// 장르 별 플레이 수로 정렬
		List<String> sumKeys = new ArrayList<>(sum.keySet());
		Collections.sort(sumKeys, (o1, o2) -> (sum.get(o2).compareTo(sum.get(o1))));

		for (String k : sumKeys) {
			// 노래 별 플레이 수로 정렬
			List<Integer> listKeys = new ArrayList<>(list.get(k).keySet());
			Collections.sort(listKeys, (o1, o2) -> (list.get(k).get(o2).compareTo(list.get(k).get(o1))));

			for (int i = 0; i < 2 && i < listKeys.size(); i++) {
				answer.add(listKeys.get(i));
			}
		}
        
		return answer.toArray(new Integer[answer.size()]);
	}
}

 

문제를 풀기 위해 (장르 : 노래가 재생된 횟수) 를 갖는 sum 이라는 Map, (장르, 노래 리스트(Map)) 를 갖는 list 라는 Map 두개를 사용했습니다.

 

먼저 장르 별로 속한 노래가 많이 재생된 순으로 정렬을 합니다. Map 에서 value 로 정렬하는 방법을 이참에 확실히 알아 놓읍시다!! 

List<String> sumKeys = new ArrayList<>(sum.keySet());
Collections.sort(sumKeys, (o1, o2) -> (sum.get(o2).compareTo(sum.get(o1))));

 

오름차순으로 하려면 o1과 o2를 바꾸면 되겠졍. ㅎㅎ

 

암튼 이 문제는 value 로 정렬만 하면 끝입니다. 내림차순으로 정렬된 값을 갖고 고기 안에서 또 노래들을 재생 횟수에 대해서 내림차순으로 정렬하면 됩니다. 각 장르에서 최대 두 개를 선택할 수 있으므로 i < 2 && i < listKeys.size() 로 해버리면 간편하지용.

 

 

오랜만에 프로그래머스에서 풀어보아씀니다.

감사합니다!!!