알고리즘/프로그래머스 Level1

[프로그래머스,java] Level1: 체육복 (2021년 7월 28일 업데이트버전)

류창 2021. 8. 6. 18:29
반응형

문제분석:

레벨 1치고는 꽤 어렵고 함정이 많은문제다.

 

reserve가  reserve번호에 1차이가나면 lost에게 빌려줄수있다. 

 

만약, reserve가 lost당햇다면, 빌려줄수 없다. 즉, 배열에서 제외 시켜버려야한다.

 

배열은 이미 선언해버린 시점에서 삭제가 안되니, 제외할 원소를 음수로 변형(-1) 시킬 예정이다.

 

여기서 많은사람이 간과 하는게 제한사항 5번이다.

 

제한사항 5번을 최 우 선 처리해야지 문제가 일어나지않는다.

 

왜냐? n= 5 lost[1,2,3]  reserve[2,3,4] 라고 생각해보자.

 

5번을 나중에 처리한다고 생각해보자. 1->2번을 빌리고 2->3번  3->4번 을 빌린다. 이렇게 빌리면 5명모두가 가능하다.

 

5번을 최우선 처리하면, 2,3은 배열 에서 제외(변형)대어, lost[1,-1,-1] reserve [-1,-1,4]가 된다.

 

1번학생은 빌릴 학생이없기때문에 4명만이 가능하다. 

 

문제풀이:

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
import java.util.*;
class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
            int answer = n - lost.length;
 
        //여분 체육복이 있지만 체육복을 잃어버린 학생을 제거
        for (int i = 0; i < lost.length; i++) {
            for (int j = 0; j < reserve.length; j++) {
                if (lost[i] == reserve[j]) {
                    answer++;
                    lost[i] = reserve[j] = -1;
                    break;
                }
            }
        }
 
        //체육복을 reserve
        for (int lostPerson : lost) {
            for (int i = 0; i < reserve.length; i++) {
                if (reserve[i] == lostPerson + 1 || reserve[i] == lostPerson - 1) {
                    answer++;
                    reserve[i] = -1;
                    break;
                }
            }
        }
        return answer;
    }
}
cs

 

하지만 이 푸는방식이 2021년 7월28일 테스트케이스 13번으로인해 정확성 100%가 아니게되었다.

 

그 이유가 무엇일까??라고 생각햇다.

 

//모르겟다.. 전혀모르겟다... 아래 다른 정답안과 비교했을때 무슨차이인지 감이안온다..

혹시 이 글을 읽으시는분은 무슨차이가있는지 댓글로 지적해주시길 바랍니다.//

 

해결했다. Arrays.sort(lost); Arrays.sort(reserve); 을

넣어줬더니 해결이 되었다. 

보아하니, {1,2,3,4,5} 를 {1,5,4,2,3}처럼 섞어논거같다. 

 

1~12번 테케는 모두 정렬 된상태로 넣었는데13번만 정렬이 안대있는것같다.

 

이런 테스트케이스를 넣을거라면, 정렬을 하라고 문제에 써줫으면좋겠다.

전혀 Level1 같지않은 문제같았다.

 

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
class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int[] people = new int[n];
        int answer = n;
 
        for (int l : lost) 
            people[l-1]--;
        for (int r : reserve) 
            people[r-1]++;
 
        for (int i = 0; i < people.length; i++) {
            if(people[i] == -1) {
                if(i-1>=0 && people[i-1== 1) {
                    people[i]++;
                    people[i-1]--;
                }else if(i+1< people.length && people[i+1== 1) {
                    people[i]++;
                    people[i+1]--;
                }else 
                    answer--;
            }
        }
        return answer;
    }
}
 
cs

 

이 답안이 테케 13번을 만족하여  체육복을 입을수있는사람을 구할수있다.

무엇보다도 반복을 많이 줄였다!

 

리뷰를하자면,

 

3:새로운 배열 people[n] 배열을 생성한다. 처음 배열을 생성하고 선언을 안하면 default로

  n사이즈만큼 원소 0을 부여한다. 즉 , people[n]= {0,0,0,0,0,...]상태란것이다.

 

4:처음 answer값을 모든학생으로 초기화

 

6~9:lost에 해당하는 번호 -1인 위치값에 -1한다. //이렇게하면 lost인 사람만 -1

    reserve에 해당하는 번호 -1인 위치값에 +1한다. //이렇게하면 reserve인 사람만 +1

    //lost며 reserve인 사람은 0이된다. 

 

11~20: people배열을 순회하며 -1(잃어버리기만한사람) 을 찾는다.

          찾았다면, people[i-1]과 people[i+1]이 1인 사람(여분이남는사람)을 찾는다.

          // if(i-1>=0 && people[i-1== 1) 에서 i-1>0은 i가 0번째면 index오류가 나기때문이다. i가 0번째면

            if(i+1< people.length && people[i+1== 1) 여기서 처리하면된다.

            반대로 i가 n인경우도 역이 성립한다. 

 

          사람을 찾았다면, 여분이남는사람은 -1을해주고 잃어버린사람은 +1을해준다.

          찾지못했다면, 체육복을 입지못햇으므로 answer값에 -1을 해준다.

반응형