티스토리 뷰

항상 문제의 조건을 유심히 파악할 것(3시간을 날렸다느뉴ㅠ)

 

 

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42862

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

처음 문제를 보고 해시맵을 사용하여 체육복이 있지만 여벌이 없는 경우 = 1 , 체육복 없는 경우 = 0, 빌려줄 수 있는 경우 = 2 로 value 를 매겨 for문을 돌아 값을 찾아 answer 에 넣어주는 식으로 코드를 짰다.

 

뭔지 모르게 끄적거림..

 

public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;
        HashMap<Integer,Integer> list = new HashMap<>(); // 번호 : 체육복 개수

        for (int i = 1 ; i <= n ; i++){
            list.put(i, 1);
        }
        Iterator<Integer> keys = list.keySet().iterator();
        while (keys.hasNext()){
            Integer keyVal = keys.next();
            for (int i = 0 ; i < reserve.length; i++){
                if (keyVal == reserve[i]) list.put(keyVal,2);
            }
        }

        Iterator<Integer> key = list.keySet().iterator();
        while (key.hasNext()){
            Integer keyVal = key.next();
            for (int i = 0 ; i < lost.length; i++){
                if (keyVal == lost[i]) list.put(keyVal,list.get(keyVal)-1);
            }
        }

        for(int i = 1 ; i <= list.size(); i ++){
            Integer value = list.get(i);
            if (value.intValue() == 0){ // 체육복 없을 때
                if (list.get(i-1) > 1 || list.get(i+1) > 1){ // 체육복 1개거나 0은 제외
                    if (list.get(i-1) >= list.get(i+1)){ //2번이 체육복 없으면 1,3번 체육복 개수 비교. 지금은 1이 더 많은 경우 , 2,0,1 ..
                    list.put(i-1,list.get(i-1)-1); // 1번 개수 하나 줄임
                    list.put(i,1);
                    }else{
                        list.put(i+1,list.get(i+1)-1); // 3번 개수 하나 줄임
                        list.put(i,1);
                    }
                }else continue;
            }
        }

        Iterator<Integer> values = list.values().iterator();
        while (values.hasNext()){
            Integer val = values.next();
            if (val != 0){answer++;}
        }
        return answer;
    }

 

근데 웬걸 에러가 발생했다.

 

런타임.. 에러?

 

이 코드에 치명적인 문제가 있었다 . n =3 , lost = [3] , reserve =[1] 로 생각해보자. 총 3명의 학생이 있고 3번 학생의 체육복 개수가 0 이면 2번 학생의 체육복 개수가 1이라 빌려줄 수가 없다. 또한 4번 학생은 없기에 해당 로직으론 오류가 날 것이다.

 

 

생각을 달리 해보겠다. 문제의 중요한 조건은 크게 2개다.

 

1. 체육복 개수가 없는 i번 학생은 i-1 학생 혹은 i+1 학생이 여벌이 있을 경우 빌릴 수 있다.

2. 체육복 여벌이 있지만 도난 당한 학생은 체육복을 빌려줄 수가 없다.

 

다른 사람의 풀이를 참고하여 생각해보니 굳이 해시맵을 사용해야 하나 싶었다.

 

결론적으로 answer는 체육복을 가지고 있는 학생의 수의 max값을 찾는거다. 
그렇기에 기존 체육복을 가지고있는 학생수 + 2번의 케이스 + 1번의 케이스를 더하면 되는거다! (복잡하게 생각 nono)

 

 

풀이

 

 

 

 public int solution(int n, int[] lost, int[] reserve) {

        // 총 학생 수 - 도난 당한 학생 수
        int answer  = 0;
        answer = n - lost.length;

        Arrays.sort(lost);
        Arrays.sort(reserve);

        // 여벌이 있지만 도난 당해서 빌려줄 수 없는 학생 수
        for (int i = 0  ; i < reserve.length ; i++ ){
            for (int j = 0 ; j < lost.length ; j++){
                if (reserve[i] == lost[j]){
                    answer ++;
                    lost[j] = -1;
                    reserve[i] = -1;
                    break;
                }
            }
        }

        // 도난을 당했지만 체육복을 빌릴 수 있는 학생 수
        for (int i = 0 ; i < lost.length ; i++ ) {
            for (int j = 0 ; j < reserve.length ; j++){
                if (lost[i]-1 == reserve[j] || lost[i] +1 == reserve[j]) {
                    answer ++;
                    reserve[j] = -1;
                    break;
                }
            }
        }
        return answer;
    }

 

 

언제나 기분좋은 파란 글짜

Lv.1 도 허덕대고 있다니... 빨리 쫓아가자..!