점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
이 문제는 그리디 알고리즘의 기본문제라고 할 수 있다.
우선 체육복을 1개만 가지고 있는 student배열을 만들어준다.
다음, lost배열이 체육복을 잃어버린 친구들이기에 student배열에
lost의 값이 포함되어 있는 친구들은 체육복의 개수를 -1씩 시킨다.
이와 마찬가지로, reserve, 즉 여벌의 옷을 가지고 있다면
체육복의 개수를 +1 시켜준다.
그리고, 이 문제는 그리디 알고리즘이기 때문에 student배열의 첫번째 인덱스 값이 2이면 뒤에 학생밖에 줄수가 없다. 그러므로 뒤에학생한테 +1값, 원래는 체육복을 줬다면 student[1]-=1; 을 시켜야 하지만 결과값에는 영향을 안끼치므로 그대로 나두었다.
마찬가지로 student배열 마지막인덱스도 값이 2이고 뒤에 인덱스는 없으므로 앞에 친구한테만 준다.
이제 그 이외에 인덱스는 예를 들어 0, 2, 0이 주어진다면 중간에 있는 학생은 앞에 학생한테 우선적으로 여벌을 주어야 한다. 그 이유는 앞에 학생의 여벌옷은 첫번째 인덱스를 제외하고 그 뒤에 학생만 이 학생에게 옷을 줄 수 있기 때문이다.
import java.util.*;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
int answer = 0;
int student[]=new int[n+1];
Arrays.fill(student, 1);
for(int i=1; i<=lost.length; i++)
student[lost[i-1]]-=1;
for(int i=1; i<=reserve.length; i++)
student[reserve[i-1]]+=1;
for(int i=1; i<=n; i++)
{
if(i==1 && student[i]==2)
{
if(student[i+1]==0)
student[i+1]+=1;
}
else if(i==n && student[i]==2)
{
if(student[i-1]==0)
student[i-1]+=1;
}
else if((i>1 && i<n) && student[i]==2)
{
if(student[i-1]==0 && student[i+1]==0)
student[i-1]+=1;
else if(student[i-1]==0)
student[i-1]+=1;
else if(student[i+1]==0)
student[i+1]+=1;
}
}
for(int i=1; i<=n; i++)
{
if(student[i]>=1)
answer++;
}
return answer;
}
}