Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

걸음마부터 달리기

완주하지 못한 선수 (해시의 getOrDefault와 Map에서의 순회) 본문

카테고리 없음

완주하지 못한 선수 (해시의 getOrDefault와 Map에서의 순회)

성추 2025. 5. 18. 16:40

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

import java.util.*;
class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer="";
        Map<String,Integer> map = new HashMap<>();
        for(String key : participant){
            if(map.containsKey(key)){
                map.put(key,map.get(key)+1);
            }
            else{
                map.put(key,1);
            }
        }
        for(String str : completion){
            map.put(str,map.get(str)-1);
        }
        for(String key: participant){
            if(map.get(key)>0){
                answer=key;
                break;
            }
        }
        

        return answer;
    }
}

간단히 보이는 문제이지만 그래도 연습차원이니 최대한 시간복잡도 줄여볼려고 아래와 같이 해봤다

 

import java.util.*;
class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer="";
        Map<String,Integer> map = new HashMap<>();
        for(String key : completion){
            if(map.containsKey(key)){
                map.put(key,map.get(key)+1);
            }
            else{
                map.put(key,1);                
            }
            
        }
        for(String key : participant){
            if(map.containsKey(key)){
                map.put(key,map.get(key)-1);
                int count = map.get(key);
                if(count==-1){
                    answer=key;
                    break;
                }
                
            }
            else{
                answer=key;
                break;
            }
        }
        return answer;
    }
}

 

음... 반복문을 여러번 안돌리고 하나의 반복문 안에서 최대한 해결하려하니 이렇게 됐다.

첫번째 풀이와는 반대로 먼저 Completions을 가지고 해시를 만들고 나서 Participants로 Completions을 접근하여

해당 Participants를 key로 쓴 value값이 -1이거나 해당 key값 자체가 Map에 안들어있으면 그게 완주 못한 사람이니 break 시키고 출력해줬다.

 

 

Map 순회

Map을 순회하면 참 편하겠는데... 라는 생각을 매번 한다.

이번에 외워두자.

 

2가지 방법이 있다. (더 있지만 코테용)

2가지 모두 keySet()을 이용해 Key들을 Set의 Collections로 가져온다.

 

Iterator<String> keys = map.keySet().iterator();
while(keys.hasNext()){
String value = map.get(keys.next());
}

이처럼 Iterator을 사용하면 된다.

 

for(String key : map.keySet()){
map.get(key);
}

향상된 for문을 쓰면 가능하다.

 

 

하지만 위와 같이 둘다 반복문을 돌때 map에 대해서 구조를 바꾸면 (put,remove) 동시성에 문제가 생길 수 있다.

 

 

getOrDefault()

내 코드를 보면 해당 key가 있는지 없는지 먼저 containsKey()로 if를 통해 확인하고

있을때, 없을때를 분기해서 코드를 작성했다.

 

V getOrDefault(Object key, V defaultValue)

key로 찾아보고 있으면 그 key에 대한 value 반환,

없으면 null주는것과 달리 defaultValue로 반환

 

 

내 로직을 잘 써보면

import java.util.HashMap;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> hm = new HashMap<>();
        for (String player : participant) hm.put(player, hm.getOrDefault(player, 0) + 1);
        for (String player : completion) hm.put(player, hm.get(player) - 1);

        for (String key : hm.keySet()) {
            if (hm.get(key) != 0){
                answer = key;
            }
        }
        return answer;
    }
}

이러지 않을까