[코딩테스트연습] 체육복

LaStella·2021년 10월 27일
0

- 전체코드

import java.util.*;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;

        //ArrayList로 변환
        ArrayList<Integer> lostList = new ArrayList<>();
        ArrayList<Integer> reserveList = new ArrayList<>();

        for(int temp : lost) {
            lostList.add(temp);
        }
        for(int temp : reserve) {
            reserveList.add(temp);
        }
        
        // lost [4, 2], reserve [3, 5] 와 같은 입력이 들어올경우 문제가 되므로 정렬
        lostList.sort(Comparator.naturalOrder());
        reserveList.sort(Comparator.naturalOrder());
        
        //체육복을 도난 당한사람들 중 여벌의 체육복을 가진경우 제거
        for(Iterator<Integer> lostIt = lostList.iterator(); lostIt.hasNext();) {
            int lostNum = lostIt.next();
            for(Iterator<Integer> reserveIt = reserveList.iterator(); reserveIt.hasNext();) {
                int reserveNum = reserveIt.next();
                if(lostNum == reserveNum) {
                    lostIt.remove();
                    reserveIt.remove();
                    break;
                }
            }
        }
        
        //체육복을 도난당한 학생의 앞번호나 뒷번호가 여벌의 체육복이 있을 경우 빌려줌
        for(Iterator<Integer> it = lostList.iterator(); it.hasNext();) {
            answer--;
            int itNum = it.next();
            if(reserveList.contains(itNum-1)) {
                    answer++;
                    reserveList.remove(reserveList.indexOf(itNum-1));
                    it.remove();
            }
            else if(reserveList.contains(itNum+1)) {
                    answer++;
                    reserveList.remove(reserveList.indexOf(itNum+1));
                    it.remove();
            }
        }
        
        answer += n;
    
        return answer;
    }
}

- 전체코드2

import java.util.Arrays;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;
        
        Arrays.sort(lost);
        Arrays.sort(reserve);
        
        for(int i=0; i<lost.length; i++){
            for(int j=0; j<reserve.length; j++){
                if(lost[i] == reserve[j]){
                    lost[i] = -1;
                    reserve[j] = -1; 
                    break;
                }
            }
        }
        
        for(int i=0; i<lost.length; i++){
            if(lost[i] != -1){
                answer--;    
            }
            for(int j = 0 ; j < reserve.length ; j++) {
                if(lost[i]-1 == reserve[j]) {
                    answer++;
                    reserve[j] = -1; 
                    break; 
                }
                else if(lost[i]+1 == reserve[j]) {
                    answer++;
                    reserve[j] = -1; 
                    break; 
                }
            }
        }
        
        answer += n;
        
        return answer;
    }
}

- 오류코드

        for(int i = 0 ; i < lostList.size() ; i++) {
            if(reserveList.contains(lostList.get(i))) {
            	lostList.remove(i);
                reserveList.remove(reserveList.indexOf(lostList.get(i)));
            }
        }

- 막혔던점 & 해경방법

  1. 처음 문제를 보고 굉장히 쉬운 문제인 줄 알고 풀었다. 단순하게 lost 배열과 reserve 배열에서 값을 삭제하는 대신 음수 값을 넣어 해결하였다. lost 배열과 reserve 배열에서 같은 값이 있는 경우 체육복을 도난당함과 동시에 여벌이 있으므로 해당 값에 음수 값을 넣은 후 lost 배열에서 나온 값의 앞번호와 뒷번호의 여벌체육복을 확인하여 있으면 음수 값을 넣었다. 그러나 채점결과 테스트13과 테스트18에서 실패가 나왔다. 어떤 경우에 실패인지 테스트 케이스를 찾던 중 lost 배열이 [4, 2], reserve 배열이 [3, 5]와 같이 lost 배열이나 reserve 배열이 역순으로 들어오면 실패한다는 것을 발견하였다. 문제에서 정렬된 값을 준다고 한 적이 없었기에 lost 배열과 reserve 배열을 정렬하여 문제를 해결하였다.
  2. 문제는 풀었으나 배열의 삭제할 값에 음수 값을 넣어 푼 것이 만족스럽지 못하였다. 그래서 삭제할 값은 삭제하는 코드를 만들기 시작했다. 배열은 값을 삭제하는데 까다로운 부분이 있으므로 이를 ArrayList로 변환하였다. 전체코드2와 같이 만들었으나 값을 삭제하는 과정에서 문제가 발생하였다. 삭제되어야 할 값이 정상적으로 삭제되지 않고 남아있는 문제였다. 오류코드를 보면 for문 내에서 remove()메소드가 호출될 경우 현재 수행 중인 for문의 lostList에서 삭제된 값의 자리로 이후 값들이 당겨지면서 채워지기 때문에 lostList에서 건너뛰는 부분이 있었다. 이 문제를 해결하기 위해서는 삭제될 경우 인덱스로 쓰이는 i의 값을 -1하여 삭제된 값이 채워지는 부분을 다시 확인하는 방법과 반복자(Iterator)를 사용하여 값을 제거하는 방법 두 가지 방법을 찾았으며 코드로 적용한 방법은 후자다.참고글

- 느낀점

이미 만들어둔 코드인 전체코드2에서 전체코드로 완성하기까지 한번에 너무 많은 양의 코드를 바꾸는 바람에 문제가 발생한 부분을 파악하고 해결하는데 시간이 너무 오래 걸렸다. 다음부터는 좀 더 작은 케이스 단위로 쪼개어 변경해야겠다. 그리고 List의 삭제과정에서 뒤에 있는 원소들이 앞으로 당겨지기 때문에 for문에서 remove()메소드를 사용할 때 발생하는 문제를 알게 되어 다행이다.

profile
개발자가 되어가는 중...

0개의 댓글