코딩 테스트 연습 - 체육복

KimDaeYoung·2021년 6월 11일
0
post-thumbnail

문항

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

제한사항

• 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.

여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

접근

배열의 includes, filter method를 이용하려하였다. 잃어버린 사람의 번호를 3가지 경우로 나눠서 여유분이 있는 경우를 includes method로 확인하고 있을 경우 filter를 이용하여 reserve에 해당하는 요소를 지우는 식으로 진행하려하였다.

오류 사항

제한사항에 대한 내용을 정확히 읽지 않고 들어가서 제한사항 2번째에 있는 내용을 코드에 반영하지 못해서 계속해서 테스트 오류가 발생했다. 그래서 본래 적은 코드에 진짜로 잃어버린 경우와 진짜로 여분이 있는 경우를 반영하는 코드를 추가해주니, 테스트를 통과하였다.

나의 코드

function solution(n, lost, reserve) {
//n = 전체학급수, lost = 도난당한 학생의 배열, reserve = 여유분을 가져온 학생의 배열

	var answer = n;
    let trueReserve = [];
    
    //진짜로 여분의 체육복이 있는 학생과 진짜 없는 학생을 구분하는 반복문
    for(let i = 0; i < reserve.length; i++) {
        if( lost.includes(reserve[i]) ) {
            lost = lost.filter( ele => ele !== reserve[i] );
        } else {
            trueReserve.push(reserve[i]);
        }
    }
	
    //일단 체육복을 정말 잃어버린 학생수 
    let failNumber = lost.length;
	
    //진짜 체육복이 있는 학생과 없는 학생을 비교하여 빌린 학생이 발생할 경우 : failNumber에서 하나씩 빼주는 모습
    for(let i = 0; i < lost.length; i++) {
        if( trueReserve.includes(lost[i]) ) {
            failNumber--;
            trueReserve = trueReserve.filter((element) => element !== lost[i] )
        } else if ( trueReserve.includes(lost[i] + 1) ) {
            failNumber--;
            trueReserve = trueReserve.filter((element) => element !== lost[i] + 1 )
        } else if ( trueReserve.includes(lost[i] - 1) ) {
            failNumber--;
            trueReserve = trueReserve.filter((element) => element !== lost[i] - 1 )
        }
    }
    
    //빌리는 과정까지 진행한 후 전체 학생수 - 빌릴수도 없는 학생수를 하여 answer를 return하는 모습
    answer -= failNumber;
    return answer;
}

탐욕법

그리디 알고리즘은 동적 프로그래밍 사용 시 지나치게 많은 일을 한다는 것에서 착안하여 고안된 알고리즘입니다. 동적 프로그래밍을 대체하는 것은 아니고 같이 쓰이며 서로 보완하는 개념입니다.

그리디 알고리즘은 탐욕 알고리즘 또는 욕심쟁이 알고리즘이라고도 불리는데요. 미래를 생각하지 않고 각 단계에서 가장 최선의 선택을 하는 기법입니다. 이렇게 각 단계에서 최선의 선택을 한 것이 전체적으로도 최선이길 바라는 알고리즘이죠.

그리디 알고리즘이 적용된 코드

function solution(n, lost, reserve) {      
    return n - lost.filter(a => {
        const b = reserve.find(r => Math.abs(r-a) <= 1)
        if(!b) return true
        reserve = reserve.filter(r => r !== b)
    }).length
}

여벌은 챙겼으나 도난당한 경우가 생각은 안되어있으나, 가장 그리디한 코드

profile
개발자로 진화중 ...

0개의 댓글