점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
∙ 전체 학생의 수는 2명 이상 30명 이하입니다.
∙ 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
∙ 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
∙ 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
∙ 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.
입출력 예 설명
예제 #1
1번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 학생 5명이 체육수업을 들을 수 있습니다.
예제 #2
3번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 학생 4명이 체육수업을 들을 수 있습니다.
지난번엔 구명보트가 모든 사람을 '최소'의 보트로 나누어 태우는 것이었다면,
체육복 문제는 주어진 조건에 따라 '최대'한 많은 학생이 입을 수 있도록 하는 것.
function solution( n, lost, reserve){
let answer = n - lost.length;
for( let i = 0 ; i < lost.length ; i++){
let lostman = lost[i];
let foreStudent = reserve.find( value => lostman - 1 === value);
let backStudent = reserve.find( value => lostman + 1 === value);
if( foreStudent ){
reserve.splice( reserve.indexOf(foreStudent) , 1);
answer++;
}else if( backStudent ){
reserve.splice( reserve.indexOf(backStudent) , 1);
answer++;
}
}
return answer;
}
1) 일단, 무조건 수업에 들어갈 수 있는 학생의 수를 answer에 할당한다.
n명의 학생 중 lost 배열에 담긴 학생의 수를 뺀다.
2) foreStudent, backStudent를 통해 체육복을 잃어버린 학생의 앞 뒤
친구들이 reserve 배열에 있는지 체크한다.
3) if문으로 앞 학생, 뒤 학생이 여벌이 있는 경우로 분리해서 있으면
그 여벌이 있는 학생을 reserve배열에서 삭제한다. 한 벌만 빌려줄 수 있으므로 중복을 피해야 하기 때문이다.
하지만 정확성 점수에서 75점뿐이다. 따라서 참고한 모범 답안은 다음과 같다.
function solution(n, lost, reserve){
let answer = 0;
let student = [];
let reserveTmp = [];
for( let i = 0; i < n ; i++) student.push(true);
lost.forEach(lostIndex => { student[lostIndex - 1] = false});
reserve.forEach(reserveIndex => {
if( student[reserveIndex - 1] === false){
student[reserveIndex - 1] = true;
// 내가 생각하지 못했던 부분 => 여벌이 있다가 잃어버린 케이스
}else{
reserveTmp.push(reserveIndex);
}
})
reserveTmp.forEach(reserveIndex => {
if(reserveIndex - 2 >= 0 && student[reserveIndex - 2] === false){ // 앞 사람이 잃어버렸을 떄, student 배열에서 최소 인덱스는 1이어야 한다.(학생번호 reserveIndex로는 2번부터)
student[reserveIndex - 2] = true;
}else if(student[reserveIndex] === false){ // 뒷 사람이 잃어버렸을 때
student[reserveIndex] = true;
}
})
answer = student.reduce( (acc, cur) => { return acc + cur}, 0);
return answer;
}