[프로그래머스] 체육복

효다몬·2022년 4월 28일
0

문제 설명

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

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

제한사항

전체 학생의 수는 2명 이상 30명 이하입니다.
체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다. (이게 중요)

입출력 예

n lost reserve return
5 [2, 4][1, 3, 5] 5
5 [2, 4][3] 4
3 [3][1] 2

예제 #1

1번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 학생 5명이 체육수업을 들을 수 있습니다.

예제 #2

3번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 학생 4명이 체육수업을 들을 수 있습니다.

나의 풀이

  1. 1~n까지의 숫자가 들어있는 배열 std을 만들어준다.

  2. lost, reverse 배열을 오름차순으로 정렬한다.

  3. 제한사항 5 번째를 해결하기 위해 lost와 reverse에 중복되는 값을 삭제해준다.
    (이거 때문에 테스트 5, 12에서 자꾸 실패했었음 😂)
    -> 본인 체육복이 도난 당했을 때, 여분을 남에게 줄 수 없으므로 미리 제외시켜준다!

  4. lost를 반복문을 통해 돌며, -1 ~ +1 값(앞, 뒤 학생)이 여분이 있으면 넘어가고 여분이 없으면 std 배열에서 그 값을 빼준다.

  5. std배열의 길이(체육복이 있는 학생) 출력

def solution(n, lost, reserve):
    std = []
    for i in range(n) :
        std.append(i+1)

    lost.sort()
    reserve.sort()

    for i in lost :
        if i in reserve :
            lost.remove(i)
            reserve.remove(i)
    
    for i in lost :
        if i in reserve:
            reserve.remove(i)
            continue
        elif i-1 in reserve:
            reserve.remove(i-1)
            continue
        elif i+1 in reserve:
            reserve.remove(i+1)
            continue
        else :
            std.remove(i)

    return len(std)

다른 사람의 풀이

def solution(n, lost, reserve):
    set_reserve=set(reserve)-set(lost)
    set_lost = set(lost)-set(reserve)
    for i in set_reserve:
        if i-1 in set_lost:
            set_lost.remove(i-1)
        elif i+1 in set_lost:
            set_lost.remove(i+1)
    return n-len(set_lost)

느낀점

다른 사람의 풀이를 보며 새로운 배열(std)을 만들고, 정렬(sort)해주고, 중복된 값을 빼주는 과정을 집합 자료형인 set을 이용하면 한방에 해결된 다는 것을 깨달았다. 다시 한번 자료형에 대해서 공부하면서 정리해야겠다.

그리고 생각보다 예외 처리하는 것에 시간이 정말 오래걸렸다. 테스트 케이스 한 곳을 해결하면 다른 한 곳에서 실패하게 되는 것이 반복됐다. 문제를 제대로 이해하고 설계하면 자동적으로 예외처리도 해결 될 것이니, 설계 과정에 더 집중해서 공부해야겠다.

코딩을 시작한 지 꽤 되었지만, 아직도 이렇게 간단한 알고리즘 문제를 풀 때 요지를 파악하고 설계하는 시간이 오래걸린 다는게 창피했다.

될 수 있으면 하루에 한 문제씩 꼭 풀어보는 시간을 가져야겠다.

profile
개발로 나를 계발하다.

0개의 댓글

관련 채용 정보