코딩테스트/Implementation (구현)

[프로그래머스] level 1 완주하지 못한 선수 (파이썬, 자바)

leejunkim 2025. 6. 30. 21:44

문제 설명

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

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

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

 

입출력 예:

문제 풀이

 

첫번째로 시도했던 코드:

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

 

로직은 완주한 사람들의 이름이 담긴 completion에 이름이 있으면 participant에서도 빼주는 것이였다. 그러면 결과적으로 완주하지 못한 사람만 남으므로 그 사람의 이름만 돌려주면 됐었다.

테스트는 다 통과했지만 효율성에서 다 떨어졌다 ㅋㅋ

그 이유는 아마 remove에 있을 텐데, 리스트에서 값이 삭제되면 그 이후의 값들의 인덱스 조정이 필요해서 효율성이 너무 나쁘게 나온 것이다.

 

2번째 시도:

사전을 사용했다.

    participant_count = {}
    name_count = {}
    
    for p in participant:
        participant_count[p] = 0
        name_count[p] = 0
        
    for p in participant:
        participant_count[p] += participant_count.get(p, 0) + 1
        
    for c in completion:
        name_count[c] += name_count.get(c, 0) + 1
    
    for k in participant_count:
        if name_count[k] != participant_count[k]:
            return k

 

일단 내가 생각한 로직은

  • participants, completion의 사전을 각각 만든다. Key는 이름, value는 각 리스트의 이름이 나온 횟수를 기록한다.
  • 참여자 이름을 순회하고 그 이름을 key로 사용해서 participants, completion 사전에서 횟수를 가져온 후, 이 휫수가 같은지 비교한다.

근데 생각해보니까, 사전을 2개 만드는 것보다, 그냥 하나를 사용해서 횟수를 기록한 다음에, completion을 순회하면서 하나씩 decrement해줄 수도 있다는 생각이 들어서 구현해봤다.

 

name_count = {}

for p in participant:
    name_count[p] = name_count.get(p, 0) + 1

for c in completion:
    name_count[c] -= 1

for k in name_count:
    if name_count[k] != 0:
        return k

 

+ 추가로, 강사님한테 여쭤보니까 파이썬은 제공하는게 너무 많아서, 파이썬 아닌 언어로도 똑같이 풀 수 있는건 연습 하셔야 한다고 하셨다. 그래서 자바로도 풀어봤다:

import java.util.HashMap;
import java.util.Map;


class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        
        HashMap<String, Integer> name_count = new HashMap<>();
        
        for (String p : participant) {
            name_count.put(p, name_count.getOrDefault(p, 0) + 1);
        }
        
        for (String completed : completion) {
            name_count.put(completed,  name_count.get(completed) - 1);            
        }
        
        for (Map.Entry<String, Integer> entry : name_count.entrySet()) {
            if (entry.getValue() != 0){
                answer = entry.getKey();
            }
        }
        
        return answer;
        
    }
}

 

회고

  • 확실히 파이썬으로 풀고 자바로 풀어보니까 파이썬이 훨씬 쉽다는 것을 또 깨닫게 됐다. ㅋㅋ 앞으로는 그냥 자바로 해야겠다는 생각이 들었다.
  • 근데 다른 사람들이 파이썬으로 한 풀이 보니까 Counter을 사용해서 단 2줄로 문제를 푸셨는데... 넘 신기했다..