점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
n | lost | reserve | return |
---|---|---|---|
5 | [2, 4] | [1, 3, 5] | 5 |
5 | [2, 4] | [3] | 4 |
3 | [3] | [1] | 2 |
import java.util.*;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
int answer = n - lost.length;
for(int i = 0; i < reserve.length; i++){
for(int j = 0; j < lost.length; j++){
if(reserve[i] == lost[j]){
reserve[i] = -1;
lost[j] = -1;
answer++;
break;
}
}
}
for(int i = 0; i < reserve.length; i++){
for(int j = 0; j < lost.length; j++){
if(reserve[i] == -1){
break;
}else if((reserve[i]-1) == lost[j] ||
(reserve[i]+1) == lost[j] ){
lost[j] = -1;
answer++;
break;
}
}
}
return answer;
}
}
체육복을 빌려주기 전 체육 수업을 들을 수 있는 학생수는 전체 학생 수에서 도난당한 학생을 뺀 값이다. (answer = n - lost.length)
체육복이 여벌이어도 자신이 도난 당했으면 다른 학생에게 빌려주지 못하므로 reserve와 lost에 같은 요소가 있을 경우 그 두 요소값에 -1을 대입한다.
여기서 -1을 대입하는 이유는 reserve에서 lost에게 빌려주지 못하게 하기 위함이다.
체육복은 자신보다 1 작거나 1 커야 빌려줄 수 있기 때문에 reserve 요소에 1 더하거나 1 뺀 값이 lost에 있으면 그 lost요소에 -1을 대입하고 체육수업을 들을 수 있는 학생 수인 answer에 1더한다. (reserve 요소값이 -1인 경우는 건너뛴다.)
여기서 lost에 -1을 대입하는 이유는 중복하여 빌려주는 일이 없게 하기 위함이다. 만약 lost{2,3,5} , reserve{2,4}라면 4는 3에게 빌려주면 5에게는 빌려줄 수 없다.
나는 처음에 이 문제를 최종 답을 도출해 내는 과정에서 학생수(n)에서 잃어버린 학생수(lost.length)를 빼야한다고 생각했기 때문에 lost의 요소값을 제거하는 방향으로 접근했다. 그렇게 했더니 배열값을 제거할 수 있는 linked list나 array list를 사용하게 되었고 문제는 더 복잡해졌다. 풀다가 답이 안나와서 접근방식을 바꿨다. reserve에서 빌려줄 수 없는 상황이 되었을 때 -1을 대입하고 reserve 요소값이 -1이 아닐 때만 생각하는 조건을 걸어 요소값 제거와 같은 효과가 나게 하였다. 그랬더니 훨씬 간단해 졌다.