만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/programmers&bj

[JAVA] 완주하지 못한 선수

D36choi 2022. 2. 9. 16:21
728x90

문제

https://programmers.co.kr/learn/courses/30/lessons/42576?language=java 

 

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

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

programmers.co.kr

풀이

프로그래머스 문제는 전부 파이썬으로 풀었다. 이제는 자바로 풀어보자. ㅎ

 

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        Map <String,Integer> completionMembers = new HashMap<String,Integer>();
        for (String member : completion) {
            int x = 1;
            if(completionMembers.containsKey(member)) {
                x = completionMembers.get(member) + 1;
            }
            completionMembers.put(member,x);
        }
        
        for (String runner : participant) {
            if (completionMembers.get(runner) == null || completionMembers.get(runner) == 0 || !completionMembers.containsKey(runner)) {
                return runner;
            }
            completionMembers.put(runner,(completionMembers.get(runner) - 1));
        }
        
        return "";
    }
}

자바로 시작해보니

1. 자바로 푸니 생각보다 재밌다

2. 자바로 푸니 생각보다 귀찮다

3. 자바로 푸니 생각보다 에러난다

4. 자동완성이 안되니 변수명이 길수록 힘들다

 

시간소모는 확실히 많이 될 듯 하다. 그래도 평소 쓰는 언어가 자바니까 도움은 더 될 것 같다.

 

스스로 피드백

다른 이들의 풀이를 바탕으로 내가 고쳐야 할 것들이 뭘까 생각했다

1. 복잡한 조건문 (무슨 or 조건을 3개나 만드냐!)

2. map 객체의 default value 값 설정

 

2번은 두고두고 쓸것 같아 정리해본다.

Map.getOrDefault(key, defaultValue) 는 key값에 해당하는 value가 없을 경우 get()은 null을 리턴하지만 이 메서드는 defaultValue를 리턴한다. 그렇기 때문에 NPE에서 자유로울 수 있고 불필요한 조건문을 통한 체크가 없어질 수 있다.

 

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        Map <String,Integer> completionMembers = new HashMap<String,Integer>();
        for (String member : completion) {
             completionMembers.put(member, completionMembers.getOrDefault(member, 0) + 1);
        }
        
        for (String runner : participant) {
            completionMembers.put(runner, completionMembers.getOrDefault(runner, 0) -1);
        }
        for (String runner : participant) {
            if (completionMembers.get(runner) != 0) {
                return runner;
            }
        }
        
        return "";
    }
}

더럽던 코드가 훨씬 깔끔해졌다. (물론 나는 맨 상단 코드로 제출했다. 아래는 두고두고 고쳐본 코드.)

 

풀면서, hash 말고 각 배열 정렬 후 각 인덱스 순서대로 비교해서 일치하지 않는 경우 그 문자열을 '완주못한 선수'로 리턴하는 로직도 생각해봤는데 역시 그렇게 푼 답변도 많았다.