본문 바로가기

코딩테스트

[프로그래머스] level1. 체육복 ( javascript)

반응형

문제

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

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

나의 풀이

21.05.16 업데이트
다시 풀어보고 업데이트 했습니다.

 

초기 코드(오답)

function solution(n, lost, reserve) {
    for(let i = 0 ; i< reserve.length;i++){
        for(let j = 0 ; j< lost.length;j++){
            if (Math.abs(reserve[i]-lost[j])<=1){
                reserve[i] = 0
                lost[j] = 0
                break;
            }
        }
    }
    return n - lost.filter(v=>v).length
}

오답 이유 ->6,12 케이스 실패
문제에는 나와있지 않지만 제한사항에 본인이 잃어버리고 본인이 여유분이 있으면, 본인이 써야되기 때문에 빌려줄 수 없다는 제한사항을 맞춰줘야된다.

 

최종코드 ( 0.16ms~0.20ms, 정답)

 

function solution(n, lost, reserve) {
    //1. 본인이 잃어버리고 본인이 여유분이 있는 경우를 먼저 판단 -> 다른사람을 빌려줄수없으므로
    for(let i = 0 ; i< reserve.length;i++){
        let haslost = lost.some((el)=> el == reserve[i])
        if (haslost){
            lost = lost.filter((el)=> el !== reserve[i])
            reserve[i] = 0;
        }
    }
    reserve = reserve.filter(v=>v)

    //2. 양 옆 사람중 여유분이 있는지 판단.
    for(let i = 0 ; i< reserve.length;i++){
        for(let j = 0 ; j< lost.length;j++){
            if (Math.abs(reserve[i]-lost[j])<=1){
                reserve[i] = 0
                lost[j] = 0
                break;
            }
        }

    }
    return n - lost.filter(v=>v).length
}

 

간단하게 for문으로 돌리면서 해당이 되면 lost와 reserve 값들을 0 으로 바꾸고 break 로 다음번호로 넘어가도록 하였다.

다른 사람 풀이 참조

방법1. (오답)

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
}

현재는 본인 자신을 판단하는 조건문이 없기에 12번 케이스에서 에러가 나지만, 너무 깔끔해서 가져왔다.
나도 이중 for문 말고, find를 통해 찾는게 더 좋았을것 같다.

 

방법2.
출처 : 출처

function lostFilter(lost, reserve, findT) {
  const filterT = { me: true, friend: false };

  return lost.filter(lostN => {
    const existI = reserve.findIndex(reserveN => filterT[findT]
                                               ? reserveN === lostN
                                               : Math.abs(reserveN - lostN) <= 1);
    if(existI === -1) return true;
    reserve.splice(existI, 1);
  });
}

function solution(n, lost, reserve) {
  const selfLost = lostFilter(lost,     reserve, 'me'    );
  const realLost = lostFilter(selfLost, reserve, 'friend');

  return n - realLost.length;
}

 

filter을 적절히 사용하면 조건에 맞는 배열을 쉽게 찾을 수 있겠다.
Math 함수를 잘 사용하자. Math.abs을 통해 절대값을 활용하는 것을 알 수 있었다.
삼항 연산자과 true false를 통해 이미 처리된 값에 대한 처리가 확실히 이루어졌다.

반응형