본문 바로가기
코딩테스트

[프로그래머스 Lv.1 / Java] 완주하지 못한 선수

by 지지 2022. 2. 13.

[문제]

완주하지 못한 선수

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

마라톤에 참여한 선수들의 이름이 담긴 배열 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[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> map = new HashMap<>();
		
        //참가한 사람들의 명단을 map에 넣기
        for(String part : participant){
            if(map.get(part) == null){
            	//map에 없으면 key를 참가자 이름으로, value를 +1해주기(기본값 0으로 설정)
                map.put(part, map.getOrDefault(part, 0) + 1);
            } else {
            	//map에 이미 이름이 있으면(동명이인) +1해주기
                map.put(part, map.get(part)+1);
            }
        }
        
        //참가자 명단을 모두 넣은 map에서 key에 완주자 이름이 있으면 value를 -1해주기 
        for(String comp : completion){
            if(map.get(comp) != null){
                map.put(comp, map.get(comp)-1);
            }
        }
        
        //key값(참가자 명단)의 value가 1이라면 그 사람이 완주하지 못한 사람이 된다!
        for(int i = 0; i<participant.length; i++){
            if(map.get(participant[i]) == 1){
                answer = participant[i];
            }
        }

        return answer;
    }
}

1. 참가자 명단을 key로, 동명이인의 수를 value로 받는 HashMap을 만들어준다.

2. 첫 번째 for문에서는 map에서 참가자들의 이름을 확인하여 이름이 없으면 이름을 key로 넣어주고, 인원을 1씩 더해

   주고, 이름이 있으면(동명이인) value를 1씩 더해주는 방식으로 map에 참가자를 모두 넣어 준다.

   - HashMap은 key의 중복을 허용하지 않기 때문에, 같은 이름의 key값이 들어오면 value가 업데이트되는 방식이다.

3. 두 번째 for문에서는 완주자 명단을 받아 완주자 명단의 이름과 key값이 일치하면 value값을 1씩 빼준다.

4. 세 번째 for문에서는 key값으로 value값을 찾아서 value값이 1이 나왔을 때의 key값을 answer에 담아준다.

   - 문제에서 완주하지 못한 선수는 딱 한 명이라고 했기 때문에, 두 번째 for문을 모두 돌리고 나면 value는 모두 0이

     되고, 딱 한 개의 Entity에서만 value값이 1이 나오게 된다!

5. 이렇게 풀어도 정확성, 효율성에서 모두 만점이 나왔다. 그러나 다른 사람의 풀이를 보면 왜 효율성을 만점을 줬는지

   이해할 수가 없다...ㅎㅎ 밑의 다른 사람의 코드를 보자.

 

● 다른 사람 풀이

import java.util.HashMap;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> map = new HashMap<>();
        
        for(String part : participant){
            map.put(part, map.getOrDefault(part, 0) + 1);
        }
        for(String comp : completion){
            map.put(comp, map.get(comp) - 1);
        }
        for(String key : map.keySet()){
            if(map.get(key) == 1){
                answer = key;
            }
        }
        return answer;
    }
}

문제를 다 풀고 뿌듯한 마음으로 다른사람의 코드를 봤는데... 오잉?

굳이 첫 번째, 두 번째 for문에서 if문을 쓸 필요가 없었다... 그렇다...ㅜㅜㅜㅜㅜ

HashMap은 key의 중복을 허용하지 않기 때문에 map에 참가자 이름이 있던 없던 계속 추가를 해주고 value값만 +1을 해주면 되는 것이었다ㅜㅜ 완주자도 마찬가지로.. 완주자 이름으로 key를 받고 value의 값을 -1해주면 된다.

마지막 for문도 나와는 다르게 깔끔하게 잘 쓰셨다... 맞네... key에 해당하는 value값이 1인걸 찾으면 되는거였네...

맞네... 나 바보였네...ㅜㅜ

물론 나의 for문이던, 이 분의 for문이던 같은 루프를 도는 기능을 하기 때문에 효율성에서 뒤쳐지지 않다고 나온 것 같다. 그러나 조금 더 깔끔한 코드를 원하는 나에게는 이 분의 코드가 더 좋아보인다!!


[느낀점]

지금까지 코딩테스트 몇 문제를 풀면서 여러가지 생각이 든다. 실수했던 부분과 무릎을 탁 쳤던 부분들을 기억하고 더 보완하고자 나열을 해보려고 한다.

 

1. 조금 더 효율적이게 for문을 써야겠다는 생각.

   - 2중for문을 쓰기 전에 한 번 더 생각해보고, 배열에 관한 것이라면 향상된 for문을 쓸 수 있지 않을까 생각해볼것.

2. 꼭 if문을 써야하는가, 써야한다면 어떻게 쓰는 것이 깔끔한가 고민하기.

   - 이번 문제와 같이 굳이 if문이 필요없는데도 if문을 쓴 것에 대해 반성을 하게 된다. 또한 흑백논리와 같은 조건이나

     짧은 조건들은 else-if문이 아닌 삼항 연산자로 더 깔끔하게 작성할 수 있는지 고민해보자.

3. collection 프레임워크에 대해 더 공부하기

   - 이걸 자료구조라고 부르는 것 같다. 처음 코딩테스트를 연습할 때는 자료구조..? 알고리즘..? 그것들이 다 뭔가 싶었

     는데, 계속 풀고 여러 정보를 얻다보니 그냥 내가 아는 collection 프레임 워크를 자료구조라고 부르는 것이다.

   - 자료구조란 프로그램에서 사용할 많은 데이타를 메모리 상에서 관리하는 여러 구현방법들을 의미한다.

   - 학원을 다닐 때 최고로 집중 못했을 때 배운게 이 파트라 늘 어려워..난 못해.. 하면서 은근히 공부하기를 피했었다.

   - 이제는 물러설 곳이 없으니 피하지 말고 열심히 공부할 것!!!!!!!!!

댓글