본문 바로가기

알고리즘/프로그래머스

[파이썬] 프로그래머 알고리즘 고득점 Kit - 해시 / 폰켓몬 완벽해설

문제

 

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

 

프로그래머스

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

programmers.co.kr

 

해설

 

이 문제의 경우 생각보다 무척 간단하게 풀 수 있다.

 

우선 "해시"를 사용하라고 되어 있기 때문에 파이썬에서 "딕셔너리" 자료 구조를 사용해줄 필요가 있다.

해시 데이터는 key - value 로 이루어진 자료 구조로 유명하다. 즉 파이썬에서 리스트의 경우 하나의 index에 해당하는 값을 저장한다고 치면, 리스트의 index가 곧 해시의 key가 되고, 해당 index에 해당하는 값이 해시의 value가 된다고 생각하면 된다.

 

그럼 왜 리스트를 안쓰고 해시를 쓰는가? 를 물어보면, 첫번째로 해시는 자료의 중복이 있을 때, 이 중복을 하나의 카테고리로 저장하는데 효율적이다. 예를 들면 이 문제의 경우 중복 없이 최대한 많은 종류의 포켓몬을 얻는 것을 목표로 한다. 그 경우 중복된 값들을 아예 하나의 카테고리로 뭉쳐 정리해주게 되면 결과적으로 "종류"의 갯수만 고려해줄 수 있게 되어 문제를 풀기가 더 수월해준다.

 

두번째로 해시는 하나의 key값을 넣어주면 그 key에 해당하는 value 값을 바로 얻을 수 있기에 데이터를 찾아 쓰는데 무척이나 효율적이다.

 

이 문제의 경우 "중복" 정보를 효율적으로 정리해주기 위해 해시를 사용해주는 것이 유리하다는 판단이 나오게 된다.

 

 

그럼 "해시" 구조를 사용한다는 가정하에, 이 문제를 어떻게 풀 수 있을까? 를 고민을 해보면 정말 간단하다.

 

nums에 박사님의 포켓몬이 담겨있을 때, 이 nums에 해당하는 포켓몬을 딕셔너리에 하나하나 담아주고, 그 종류의 갯수랑 박사님이 주기로 허용한 포켓몬의 최대 갯수를 비교하고, 만약 종류의 갯수가 더 많으면 최대 갯수를 리턴하고, 만약 최대 갯수가 더 많은 경우엔 종류의 갯수를 출력해주면 끝난다.

 

이를 코드로 작성하면 아래와 같다.

 

 

코드
def solution(nums):
    col_pok = {}
    max_pokemon = len(nums)//2
    for num in nums:
        if num not in col_pok.keys():
            col_pok[num]=1
        else:
            col_pok[num]+=1
    max_num = len(col_pok.keys())
    if (max_num > max_pokemon):
        answer = max_pokemon
    else:
        answer = max_num
    return answer

 

 

결과