[99클럽 코테 스터디 5일차 TIL] 해시

sarah·2024년 7월 26일
0

programmers

목록 보기
5/21

문제

  • 문제 설명
    수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
    마라톤에 참여한 선수들의 이름이 담긴 배열 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"
  • 입출력 예 설명
    예제 #1
    "leo"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
    예제 #2
    "vinko"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
    예제 #3
    "mislav"는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.

import java.util.HashMap;

class Solution {
    public String solution(String[] participants, String[] completions) {
        HashMap<String, Integer> participantMap = new HashMap<>();
        
        for(String participant: participants) {
            participantMap.put(
                participant,
                participantMap.getOrDefault(participant, 0) + 1
            );
        }
                
        for(String completion: completions) {
            participantMap.put(
                completion,
                participantMap.get(completion) - 1
            );
        }
        
        String notCompletedParticipant = "";
        for(String participant : participantMap.keySet()) {
            if(participantMap.get(participant) == 1) {
                notCompletedParticipant = participant;
                break;
            }
        }
        
        return notCompletedParticipant;
    }
}

해결방안

처음에 List를 사용해서 remove 하면되겠다 생각해서 아래와 같이 작성하였다.

class Solution {
    public String solution(String[] participants, String[] completions) {
        ArrayList<String> participantList = 
            new ArrayList<>(Arrays.asList(participants));
        
        for(String completion: completions) {
            participantList.remove(completion);
        }
        
        return participantList.get(0);
    }
}

코드는 정상적으로 돌아가지만 시간초과로 틀렸다.

지피티한테 물어본 결과, ArrayList.remove(Object o) 메소드는 리스트의 크기에 비례하는 시간복잡도(O(n))를 가지기 때문에, 전체 시간복잡도는 O(n * m)이 됩니다(n은 참가자 수, m은 완주자 수). 라고 했다.

그래서 HashMap은 평균적으로 O(1) 시간복잡도를 가지므로, 전체 시간복잡도는 O(n + m)이 됩니다. 라고 하여 HashMap을 사용했다.

참가자를 맵으로 만들어서 키는 참가자명, 벨류는 참가자수 저장하여 완주자를 for문으로 돌려 참가자수를 감소시켜 최종적으로 1인 참가자를 찾아서 리턴했다.

회고

시간복잡도를 생각하지 않고 풀었더니 문제 오류가 발생해서 간만에 자료구조와 시간복잡도에 대해 공부하게 되었다.
앞으로 갈길이 멀어보이지만 하나씩 풀어나가야겠다. 아좌좌~

0개의 댓글