[프로그래머스] 체육복

이한솔·2023년 10월 20일
0

프로그래머스_레벨1

목록 보기
53/65
post-thumbnail

✨️ 문제 설명

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

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

 -> 자세한 내용 보러가기

🎲 자바 풀이

  1. 첫번째 풀이
  2. class Solution {
      public int solution(int n, int[] lost, int[] reserve) {
          //가정 : 모든 학생은 체육복을 가지고 있다
          int answer = n;
          int[] students = new int[n + 1];
          for(int idx = 1; idx < students.length; idx++){
              //0번인 학생은 없음
              students[idx] = 1;
          }
    
          //도난당한 체육복
          for(int l : lost){
              students[l]--;
          }
    
          //여벌을 가진 학생들이 체육복을 빌려줌
          for(int r : reserve){
              students[r]++;
          }
    
          //학생 수 계산
    
          for (int i = 1; i <= n; i++) {
              if (students[i] == 0) { //체육복이 없다면
                  if (i > 1 && students[i - 1] == 2) {
                      //앞 번호가 빌려주거나
                      students[i]++;
                      students[i - 1]--;
                  } else if (i < n && students[i + 1] == 2) {
                      //뒷 번호가 빌려줘야함
                      students[i]++;
                      students[i + 1]--;
                  } else {
                      //그렇지 않으면 수업을 들을 수 없음.
                      answer--;
                  }
              }
          }
          return answer;
      }
    }
    
  3. 두번째 풀이
  4. import java.util.HashSet;
    import java.util.Set;
    
    class Solution {
        public int solution(int n, int[] lost, int[] reserve) {
            Set<Integer> lostSet = new HashSet<>();
            Set<Integer> reserveSet = new HashSet<>();
            
            for (int l : lost) {
                lostSet.add(l);
            }
            
            for (int r : reserve) {
                if (lostSet.contains(r)) {
                    lostSet.remove(r);
                } else {
                    reserveSet.add(r);
                }
            }
            
            for (int r : reserveSet) {
                if (lostSet.contains(r - 1)) {
                    lostSet.remove(r - 1);
                } else if (lostSet.contains(r + 1)) {
                    lostSet.remove(r + 1);
                }
            }
            
            return n - lostSet.size();
        }
    }
    

풀이 설명

1. 첫번째 풀이
: 모든 학생이 체육복을 가지고 있다는 가정 하에, 학생 수만큼의 배열을 생성하고, 기본 체육복 개수를 할당하였다.
: 그 후 잃어버린 경우 -1, 여분이 있는 경우 +1을 하여, 학생이 체육복 개수가 0일 때 앞 뒤 번호의 체육복 개수가 2라면 체육복을 빌릴 수 있는 것으로 생각하고 풀이하였다. 이 경우 배열의 길이가 길어지면 시간이 오래 걸리게 된다.

2. 두번째 풀이
: 체육복을 잃어버린 학생 번호와 여분이 있는 학생 번호를 각각의 Set에 할당한다.
: 만약 lostSet의 앞뒤번호가 reseveSet에 있다면, 잃어버린 학생은 수업을 들을 수 있으므로 lostSet에서 제거한다. 남아있는 lostSet의 size만큼은 수업을 들을 수 없는 학생이므로 전체 학생 수에서 빼서 반환한다.
: 불필요한 배열생성을 줄이고, 단일 순회로 비교할 수 있어 좀더 효율적으로 구할 수 있었다
profile
개인 공부용

0개의 댓글