본문 바로가기

자료구조 & 알고리즘

[프로그래머스] 베스트앨범 python/파이썬

 

 

이 문제의 핵심은 해쉬의 정렬에 있다. 파이썬의 Dictionary는 key값으로 해쉬를 이용하기 때문에 마치 주머니에 정보를 담듯이 순서가 없다고 한다. 그런데 정렬을 해야되는 문제가 나와서 처음엔 당황을 했다. 찾아보니 딕셔너리를 정렬하여 저장하는 방법은 나오지 않았지만 딕셔너리의 key, value 중 하나를 기준으로 정렬하여 추출하는것이 가능했다.

 

 

처음 접근:

Dict은 정렬이 불가하다 생각했기에 max1, max2 키를 추가로 만들어 정보를 담을 play[]를 순회하며 비교하여 정보를 담으려했다. 또 정답 출력시 필요한 장르의 총 재생횟수를 위해 cnt 키도 추가했다. 이 또한 구현이 가능할거 같았지만 Dict에 중복되는 정보가 담기고 구현이 복잡해지는거 같아 정렬이 가능하지 찾아보았다.

 

Dictionary(해쉬)의 정렬을 이용한 풀이:

메인 dict은 최대한 간결하게 만들었다. (2중 딕셔너리 사용)

dict={

    genre:{

        고유번호(i) : 플레이 횟수(play[i])}

    }

}

 

하지만 장르의 총 재생 횟수가 많은 순서로 배열에 담아야하기 때문에 각 장르별 count값이 추가로 필요했다. 이를 한 딕셔너리에 닮을 수 있지만 따로 빼는것이 정렬할 때 편할거 같아 cnt 딕셔너리를 생성했다.

 

cnt = { genre : count }

 

cnt를 value(count) 기준으로 정렬한 후 cnt의 key(genre)를 통해 dict[genre]으로 각 장르별 딕셔너리에 접근한다. 이후 dict[genre]를 value(play횟수)로 정렬하여 key을 answer 리스트에 담아준다. 이 때 가장 큰값 2개만 필요하기 때문에 dict[genre] 전체를 순회 할 필요가 없다. 따라서 dict[genre]를 순회 할 떄 반복 횟수를 2번으로 제한 하기 위해 [ :2 ]를

사용했다.

def solution(genres, plays):
    answer = []

    dict = {} # main dict
    cnt = {} # genre : count

    for i in range(len(plays)):
        if genres[i] in dict:
            dict[genres[i]][i] = plays[i]
        else :
            dict[genres[i]] = {
                i : plays[i]
            }

        cnt[genres[i]] = cnt.get(genres[i], 0) + plays[i]

    for (genre, count) in sorted(cnt.items(), reverse=True, key = lambda item:item[1]):
        for (key,value) in sorted(dict[genre].items(), reverse=True, key = lambda item:item[1])[:2]:
            answer.append(key)

    return answer

 

 

다른 사람의 풀이를 보니 zip과 enumerate을 이용해서 for문 내부 코드를 좀 더 간편화 할 수 있다.

defaultdict 등을 이용했지만 아직 공부하지 못한 부분이라 이해가 안갔다. 좀 더 찾아보고 다른 풀이도 추가하겠다. (2021-06-15)

 

딕셔너리 정렬 방법 참조 : https://rfriend.tistory.com/473