ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 - 완주하지 못한 선수(해시)
    코딩 테스트 2021. 4. 13. 15:09

    programmers.co.kr/learn/courses/30/lessons/42576

     

    코딩테스트 연습 - 완주하지 못한 선수

    수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수

    programmers.co.kr

    # 문제 설명

    수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

    마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

     

    # 제한사항

    • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
    • completion의 길이는 participant의 길이보다 1 작습니다.
    • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
    • 참가자 중에는 동명이인이 있을 수 있습니다.

     

    # 입출력 예

    participant completion return
    ["leo", "kiki", "eden"] ["eden", "kiki"] "leo"
    ["marina", "josipa", "nikola", "vinko", "filipa"] ["josipa" "filipa", "marina", "nikola"] "vinko"
    ["mislav", "stanko", "mislav", "ana"] ["stanko", "ana", "mislav"] "mislav"

     

    # 풀이

    - completion 리스트에서 원소를 하나씩 불러와 participant에 있으면 그 원소를 지우는 방식으로 구현해보았다.

    def solution(participant, completion):
        for c in completion:
            if c in participant:
                participant.remove(c)
        return participant[0]

    - 정확성 테스트에서는 만점을 받았지만 효율성 테스트에서 시간 초과 판정을 받았다.

    - 코드를 분석하여 시간 복잡도를 생각해보면 이중 for문을 사용한 O(N*(N-1))가 될 것임을 알 수 있다.

    - 따라서 시간 복잡도를 줄일 수 있는 방안으로 코드를 설계해야 한다.

    - 문제의 분류가 해시(hash)이므로 hash에 대해서 알아보았다.

     

    # 해시(hash)

    - hash는 각 값에 대한 고유한 정수형 숫자를 나타낸다.

    - 따라서 고유한 값을 key로 딕셔너리에 담을 수 있고, 딕셔너리에 값들을 빠르게 비교할 수 있다. (정수형 숫자이기 때문에 덧셈,

      뺄셈이 가능해진다.)

    - 숫자는 자료형이 달라도 같은 hash를 갖는다. (int -1 과 float -1.0 은 같은 hash값을 갖는다.)

    - 동명이인과 같은 문제에 사용할 수 있다.

     

    # 해시를 이용한 풀이

    - hash를 이용한 딕셔너리를 생성하고 participant와 completion 리스트의 hash 차이를 이용하여 완주하지 못한 선수를 찾으면

      된다.

    def solution(participant, completion):
        temp = 0
        dic = dict()
        for p in participant:
            dic[hash(p)] = p # 해시를 이용한 딕셔너리 생성
            temp += int(hash(p)) # participant의 전체 해시 합
        for c in completion:
            temp -= hash(c) # participant의 전체 해시 합에서 completion의 해시를 하나씩 빼준다
        return dic[temp] # 해시 차이값을 딕셔너리에 넣고 key값을 반환한다

     

    # 다른 풀이

    - collections 모듈을 활용해서 풀 수 있다.

    - collections의 내장 함수인 Counter()는 딕셔너리와 같이 hash형 자료들의 값의 개수를 셀 때 사용할 수 있다.

      -> {'자료 이름': '빈도수'}

    - Counter() 객체끼리 빼는 것도 가능(=set의 차집합)하고, 0이나 음수의 값들도 연산이 가능하다.

    - 해당 값이 없더라도 error가 아닌 0을 반환해준다.

    import collections
    
    def solution(participant, completion):
        diff = collections.Counter(participant) - collections.Counter(completion)
        return list(diff.keys())[0]

     

    # 고찰

    • 문제의 유형을 파악하는 연습이 필요하다.
    • 문제가 요구하는 정확도와 시간 복잡도를 분석해보는 것이 필요하다.

    '코딩 테스트' 카테고리의 다른 글

    프로그래머스 - 위장(해시)  (0) 2021.04.14
    프로그래머스 - 전화번호 목록(해시)  (0) 2021.04.13
    개발형 코딩 테스트  (0) 2021.04.13
    소수 판별과 구간 합  (0) 2021.04.12
    그래프 이론 - (3)  (0) 2021.04.09

    댓글

Designed by Tistory.