[프로그래머스] 체육복

ppyororong_0_0·2022년 1월 12일
0

프로그래머스

목록 보기
2/19

[프로그래머스 - 1단계] 체육복 문제

https://programmers.co.kr/learn/courses/30/lessons/42862

📝 문제 설명

전체 학생 수 : n
체육복을 도난당한 학생들의 번호가 담긴 배열 : lost
여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 : reserve
체육 수업을 들을 수 있는 학생의 최댓값 리턴

  • 여벌 체육복을 가져온 학생이 체육복을 도난당한 경우는 다른 학생에게 체육복을 빌려줄 수 없음

💡 풀이

1. 우선, 체육복을 여벌 가지고 있는데 도난 당한 학생 먼저 찾음

  • for문을 통해서 lost배열에도 속해 있고, reserve배열에도 속해 있는 학생 찾기
  • 두 배열에 속해 있다면 reserve배열에서 제거해줌
    (여벌의 체육복이 있었는데 체육복을 도난당한 학생은 자기가 입어야 하기 때문에 빌려줄 수 없다)
  • mine배열에 그러한 학생들을 다 넣어줌
  • for문을 다 돌고나면 reverse 배열에는 정말 체육복을 빌려줄 수 있는 학생들만 남게됨

2. 이제 나머지 학생들 확인

  • 도난당한 학생들 : lost 배열에 속해있으면서, mine 배열에 없으면 체육복을 빌려야 하는 학생들
  • 앞, 뒤에 존재하는 학생들에게 빌릴 수 있는지 확인
    도난당한 학생들 앞 뒤의 학생들이 reserve 배열에 있으면 그 학생의 인덱스를 찾아서 reserve배열에서 제거해줌
    (이미 빌려줬으므로 다음 학생에게 또 빌려줄 수 없으므로)
  • 도당하지 않은 학생들: lost배열에 없으면서, mine배열에도 없으면 도난당하지 않은 학생들
    (자기 체육복을 자기가 입거나, 여분의 체육복을 빌려줄 수 있다)

🖥️ 코드

function solution(n, lost, reserve) {
    var answer = 0;
    let mine = [];
      for (let i = 1; i <= n; i++) {
        if (lost.includes(i) && reserve.includes(i)) {
          let idx = reserve.indexOf(i);
          reserve.splice(idx, 1);
          answer++;
          mine.push(i);
        }
      }
      for (let i = 1; i <= n; i++) {
        if (lost.includes(i) && !mine.includes(i)) {
            if (i - 1 > 0 && reserve.includes(i-1)) {
                let idx = reserve.indexOf(i - 1);
                reserve.splice(idx, 1);
                answer++;
            } else if (i + 1 <= n && reserve.includes(i + 1)) {
                let idx = reserve.indexOf(i + 1);
                reserve.splice(idx, 1);
                answer++;
            }
        } else if(!mine.includes(i)) {
            answer++;
        }
    }
    return answer;
}


어려웠던 점

  1. 처음에 lost나 reserve 배열의 학생들 번호가 당연하게도 오름차순 순으로 정렬되어 들어올 것이라고 생각하고 코드를 짰었는데 계속 통과하지 못해서 찾아보니 [5, 3] 이런 식으로도 들어올 수 있다는 걸 깨달음
  2. 여벌 체육복이 있는 학생이 도난당할 수 있다는 점을 문제 읽을 때 읽었긴한데...코드 짜면서 간과함
  3. 코드가 중복되는 내용이 많음 -> 다른 사람들은 어떤 식으로 코드를 짰는지 참고해봐야겠다
  4. 그리디 문제라는데 그리디란 무엇인지 찾아보자

❗ 다른 사람 풀이

function solution(n, lost, reserve) {
    const students = {};  // students라는 빈 객체 생성
    let answer = 0;
    for(let i = 1; i <= n; i++){
        students[i] = 1;  // students객체의 요소들 : i를 key값으로 하면서 값이 1
    }
  
    lost.forEach(number => students[number] -= 1); 
  // students객체에서 lost배열에 있는 학생에 해당하면 그 값을 -1해줌(즉 0이 되게)
    reserve.forEach(number => students[number] += 1);
  // 다시 students객체에서 reserve배열에 있는 학생들은 그 값을 +1해줌
  // (여분이 있으면서 도난당하지 않아 체육복을 빌려줄 수 있는 학생은 2가 되고, 
  // 여분이 있었는데 도난당해 체육복을 자기가 입어야 하는 학생은 1이 됨)

    for(let i = 1; i <= n; i++){
      // 체육복이 2개인 학생들은 자기 앞 뒤에 학생들이 체육복이 0인지 보고 체육복이 없으면 자기 체육복을 빌려줌.
        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++;
        }
    }
  // students객체에서 값이 1이상인 학생들의 수가 답! 
  // (1이상인 이유는 2도 있기 때문에. 
  // 체육복이 여벌 있었으나 이미 다들 빌렸거나 아니면 사이즈가 안 맞는 이유로 빌려줄 수 없어서 2개 그대로 가지고 있을수도 있기 때문)
    return answer;
}

배운 점

  • 객체는 잘 사용하지 않았었는데 객체 활용하는 방법을 다시 한 번 생각하게 됨
  • key값을 통해 객체 값 가져오는 방법... 기억 저편에 있었는데...다시 떠올림
profile
안녕하세요!

0개의 댓글