[프로그래머스] 체육복

neoneoneo·2024년 3월 19일
0

kotlin

목록 보기
39/49

문제

체육복

요약 | n명의 학생이 있는데, 그 중 체육복을 도난 당한 학생과, 여벌의 체육복을 보유한 학생이 있다. 체육복은 번호 앞, 뒤 학생에게만 빌릴 수 있는 상황에서 최대한 몇 명의 학생이 체육복을 입을 수 있는가?

나의 풀이

class Solution {
    fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
        var spare: MutableList<Int> = MutableList(n) { 0 }
        //체육복 보유 현황 저장
        for (i in 0..n - 1) {
            if (reserve.contains(i + 1) && lost.contains(i + 1)) spare[i] += 1
            else if (reserve.contains(i + 1)) spare[i] += 2
            else if (lost.contains(i + 1)) spare[i] = 0
            else spare[i] += 1
        }
        //체육복 빌려주기
        for (i in 0..n - 2) {
            if (spare[i] > spare[i + 1] && spare[i] == 2 && spare[i + 1] == 0) {
                spare[i]--
                spare[i + 1]++
            } else if (spare[i] < spare[i + 1] && spare[i + 1] == 2 && spare[i] == 0) {
                spare[i  + 1]--
                spare[i]++
            }
        }
        return spare.count { it >= 1 }
    }
}
  1. 학생 수 만큼 리스트를 만들고 각 학생 별 체육복 수량을 저장해둔다.
  2. 체육복 수량의 i, i+1 값을 비교하면서 2-0 조합의 경우 1씩 나눠가진다.

고수의 풀이

class Solution {
        fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
            var answer = n
            var lostSet = lost.toSet() - reserve.toSet()
            var reserveSet = (reserve.toSet() - lost.toSet()) as MutableSet
            for (i in lostSet) {
                when {
                    i + 1 in reserveSet -> reserveSet.remove(i + 1)
                    i - 1 in reserveSet -> reserveSet.remove(i - 1)
                    else -> answer--
                }
            }
            return answer
        }
}
  • lostSet = lost.toSet() - reserve.toSet() : 배열을 set으로 변환하면서, lost된 학생 중 여벌이 있는 학생이 있다면(즉, reserve와 중복된 숫자가 있다면), 그 학생 번호를 제거한다.
  • reserveSet = (reserve.toSet() - lost.toSet()) as MutableSet : 이번에는 배열을 MutableSet으로 변환하면서, 여벌이 있는 학생 중 도난 당한 학생이 있다면(즉, reserve할 수 있는 학생 중 lost된 학생이라면), 그 학생 번호를 제거한다.
    • 이때, set은 MutableSet으로 변환했으므로 아래 반복문에서 remove와 같은 처리가 가능해지도록 했다.
  • for (i in lostSet) : 도난당한 학생을 한 명씩 돌면서
  • i + 1 in reserveSet -> reserveSet.remove(i + 1); i - 1 in reserveSet -> reserveSet.remove(i - 1) : 도난 당한 학생(i)의 앞, 뒤 학생이 여벌이 있는 학생 집단(reserveSet)에 있으면, 여벌 집단에서 해당 학생을 제거한다.
  • var answer = n, else -> answer-- 이므로, 이도(앞의 학생에게 빌리기) 저도(뒤의 학생에게 빌리기) 못하는 학생이 있다면 전체 학생 수에서 -1 처리한다.

배운점과 느낀점

  • 풀면서 set을 쓸 생각은 전혀 못 했는데, set의 활용에 대한 시야를 넓혀준 문제이다.
  • 가끔 다른 풀이를 보면 as가 등장하는데, 아직 코드에 어떻게 활용할 수 있는지 감이 잘 안온다. 더 많은 사례를 접하고 연습이 필요하다.
  • 간만에 서치 없이 내 힘만으로 풀어낸 문제라 뿌듯하다!

[TIL-240319]

0개의 댓글