알고리즘 풀이/프로그래머스

[Level 3] 베스트 앨범

mhko411 2021. 6. 7. 21:45
728x90

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

 

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

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

programmers.co.kr


접근

리스트와 딕셔너리를 활용하여 해를 구한다.

 

구현

- 먼저 장르를 key로 하여 (노래의 번호, 재생횟수)를 리스트에 저장한다.

- genre_play_idx의 딕셔너리에는 장르별로 리스트를 item으로 갖고 해당 리스트에는 (노래번호, 재생횟수)가 원소로 저장되어 있다.

    for idx in range(N):
        genre = genres[idx]
        play = plays[idx]
        # 장르별로 노래의 번호와 재생된 횟수를 저장한다.
        # 리스트 형태로 저장한다.
        if genre in genre_play_idx:
            genre_play_idx[genre].append((idx, play))
        else:
            genre_play_idx[genre] = [(idx, play),]

- 해당 장르별로 리스트를 재생횟수를 기준으로 내림차순 정렬한다.

    # 위에서 저장한 것에서 재생횟수를 기준으로 내림차순 정렬한다.
    for key in genre_play_idx.keys():
        genre_play_idx[key] = sorted(genre_play_idx[key], key=lambda x: -x[1])

- 가장 많이 재생된 장르를 찾기위해 장르를 key값으로 장르별 총 재생횟수를 구한다.

    genre_play_dict = dict()
    # 가장 많이 재생된 장르를 찾기위해 딕셔너리 형태로 저장한다.
    for idx in range(N):
        if genres[idx] in genre_play_dict:
            genre_play_dict[genres[idx]] += plays[idx]
        else:
            genre_play_dict[genres[idx]] = plays[idx]

- 위에서 구한 장르별 재생횟수를 리스트로 변환하고

- 재생횟수를 기준으로 내림차순으로 정렬한다.

- 해당 리스트를 순차적으로 탐색하여 해당 장르에서 2개의 노래를 뽑는다.

    genre_play_list = []
    # 위에서 구한 장르별 재생횟수를 리스트 형태로 변환하여
    # 재생횟수를 기준으로 내림차순 정렬한다.
    for key in genre_play_dict.keys():
        genre_play_list.append((key, genre_play_dict[key]))
    genre_play_list = sorted(genre_play_list, key=lambda x: -x[1])

- 재생횟수를 기준으로 내림차순 정렬된 리스트에서 순차적으로 꺼내어 

- 해당 장르에서 최대 두 개의 노래에 대한 번호를 answer에 담는다.

    # 가장 많이 재생된 장르 별로 꺼낸다.
    for i in range(len(genre_play_list)):
        key = genre_play_list[i][0]
        # 해당 장르에서 2개까지만 꺼내서 answer에 저장한다.
        for k in range(len(genre_play_idx[key])):
            if k >= 2:
                break
            answer.append(genre_play_idx[key][k][0])

전체 코드

from _collections import deque
def solution(genres, plays):
    answer = []
    N = len(genres)
    genre_play_idx = dict()
    
    for idx in range(N):
        genre = genres[idx]
        play = plays[idx]
        # 장르별로 노래의 번호와 재생된 횟수를 저장한다.
        # 리스트 형태로 저장한다.
        if genre in genre_play_idx:
            genre_play_idx[genre].append((idx, play))
        else:
            genre_play_idx[genre] = [(idx, play),]
    
    # 위에서 저장한 것에서 재생횟수를 기준으로 내림차순 정렬한다.
    for key in genre_play_idx.keys():
        genre_play_idx[key] = sorted(genre_play_idx[key], key=lambda x: -x[1])
        
    genre_play_dict = dict()
    # 가장 많이 재생된 장르를 찾기위해 딕셔너리 형태로 저장한다.
    for idx in range(N):
        if genres[idx] in genre_play_dict:
            genre_play_dict[genres[idx]] += plays[idx]
        else:
            genre_play_dict[genres[idx]] = plays[idx]
    
    genre_play_list = []
    # 위에서 구한 장르별 재생횟수를 리스트 형태로 변환하여
    # 재생횟수를 기준으로 내림차순 정렬한다.
    for key in genre_play_dict.keys():
        genre_play_list.append((key, genre_play_dict[key]))
    genre_play_list = sorted(genre_play_list, key=lambda x: -x[1])
    
    # 가장 많이 재생된 장르 별로 꺼낸다.
    for i in range(len(genre_play_list)):
        key = genre_play_list[i][0]
        # 해당 장르에서 2개까지만 꺼내서 answer에 저장한다.
        for k in range(len(genre_play_idx[key])):
            if k >= 2:
                break
            answer.append(genre_play_idx[key][k][0])
        
    return answer

'알고리즘 풀이 > 프로그래머스' 카테고리의 다른 글

[Level 1] 숫자 문자열과 영단어  (0) 2021.07.31
[Level 2] 괄호 회전하기  (0) 2021.06.15
[Level 2] 게임 맵 최단거리  (0) 2021.06.07
[Level 3] 섬 연결하기  (0) 2021.05.12
[Level 3] 등굣길  (0) 2021.04.15