코딩 테스트 일기 - 09

윤수빈·2024년 8월 20일
0
post-custom-banner

코드카타

체육복

문제 링크 : 체육복

문제 설명:

문제 풀이:

  1. 총 학생 수에 lost의 길이만큼 빼주어 사용할 체육복이 있는 학생들만 추렸다.
    answer += n-lost.length;
  2. 여벌의 체육복이 있는 학생이 도난당했을 경우를 대비하여 lost와 reserve가 같은 번호인 경우 각 배열에서 삭제해주었다.
for(let i=0; i<lost.length; i++){
        let isDuple = reserve.indexOf(lost[i]);
        
        if(isDuple !== -1) {
            reserve.splice(isDuple, 1);
            lost.splice(i, 1);
            i--;
            answer++;
        }
    }
  1. 남은 lost와 reserve의 순서가 꼬여있을 경우를 대비하여 오름차순으로 정렬해주었다.
    lost.sort((a,b) => {
        return a > b ? 1 : -1;
    });
    
    reserve.sort((a,b) => {
        return a > b ? 1 : -1;
    });
  1. 이제 학생의 수만큼 반복문을 수행하도록 하고, 체육복을 도난당한 학생들(lost) 주변으로 대여해줄 수 있는 학생들(reserve)이 있는지 탐색하였다. for(let i=1;i<=n;i++) { ... }

4-1. 내부 로직에서 첫번째로 만약 reserve의 첫번째 값이 순회하는 학생 번호보다 2이상 차이나면 대여를 해줄 수 없으니 shift() 를 반복하여 빼주기로 했다.

while(i-2>=reserve[0]) {
            reserve.shift();
        }

4-2. 순회하는 도중 학생의 번호가 lost 배열에 담겨있는 경우 reserve의 첫번째 값이 학생 번호보다 1이 작거나 1이 크면 대여가능하도록 하고, 체육복이 있는 학생의 수(answer)를 증가시켜주었다. 마지막으로는 대여를 해주었으므로 reserve 첫번째 값을 shift() 해주었다.

const isLostStudent = lost.includes(i);
        if (isLostStudent) {
            if(reserve[0] === i-1 || reserve[0] === i+1) {
                answer++;
                reserve.shift();
            }
        }

📃 전체 코드

function solution(n, lost, reserve) {
    var answer = 0;
    answer += n-lost.length;
    
    for(let i=0; i<lost.length; i++){
        let isDuple = reserve.indexOf(lost[i]);
        
        if(isDuple !== -1) {
            reserve.splice(isDuple, 1);
            lost.splice(i, 1);
            i--;
            answer++;
        }
    }
    
    lost.sort((a,b) => {
        return a > b ? 1 : -1;
    });
    
    reserve.sort((a,b) => {
        return a > b ? 1 : -1;
    });
    
    for(let i=1;i<=n;i++) {
        while(i-2>=reserve[0]) {
            reserve.shift();
        }
        
        const isLostStudent = lost.includes(i);
        if (isLostStudent) {
            if(reserve[0] === i-1 || reserve[0] === i+1) {
                answer++;
                reserve.shift();
            }
        }
    }
    
    return answer;
}

🚫 Blocked Issue

  1. 학생들의 번호가 정렬되어 있지 않을 가능성이 있다는걸 모르고 reserve.shift()를 해서 테스트 결과에 실패하고 있었다.
    => 이 부분은 정렬을 통해 해결되었다.
  2. lost와 reserve에 동일한 학생 번호가 있는지 검증하는 반복문 안에서 반복 카운트를 splice 인자로 주어서 건너뛰었던 부분이 있었다
    => 건너뛰지 않도록 splice가 발생하면 반복카운트(i)를 감소시켜주어 해결했다.

⛔ Difficult Issue

  1. 검증하기 위한 반복, 탐색을 위한 반복, 순회하기 위한 반복 등 반복하는 로직이 많아서 효율적인 스크립트는 아니라고 생각되며 학생의 수가 많아질수록 불안정하다고 느껴진다.
    => 객체를 통해 접근하는 방식을 채용하면 어떨지 고민해보다가 현재 코드로 작성하게 되었는데 다른 사람의 풀이를 보면서 내가 원했던 코드 방식이 그대로 있어서 보고 많이 배웠다.
function solution(n, lost, reserve) {
    const students = {};
    let answer = 0;
    for(let i = 1; i <= n; i++){
        students[i] = 1;
    }
    lost.forEach(number => students[number] -= 1);
    reserve.forEach(number => students[number] += 1);

    for(let i = 1; i <= n; i++){
        if(students[i] === 2 && students[i-1] === 0){
                students[i-1]++;
                students[i]--;
        } else if(students[i] === 2 && students[i+1] === 0){
                students[i+1]++;
                students[i]--;
        }
    }
    for(let key in students){
        if(students[key] >= 1){
            answer++;
        }
    }
    return answer;
}

객체의 key:value 형태를 응용해서 학생의 번호가 1~n까지 순차적이란 점을 고려해 객체를 활용한 풀이라고 생각한다.
가독성도 좋고 lost와 reserve에 대해 학생이 가진 체육복을 연산해줄 때, key에 직접 접근하여 증감시켜주는 부분이 특히 좋았다..


profile
정의로운 사회운동가
post-custom-banner

0개의 댓글