티스토리 뷰

 

코딩테스트 연습 - 체육복

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번

programmers.co.kr

POINT

여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

→ 여벌이 있고, 도난도 당한 학생을 제외하기

집합 자료형 set

  • 중복이 없다.
    • 중복이 없어서 'set1 - set2' 연산이 가능하다.
    • 중복을 제거하는 필터 역할로 종종 사용된다.
  • 순서가 없다.
str = "aabbaccc"
num1 = [3 ,6, 90, 1] # 무작위
num2 = [1, 2, 3, 4] # 1씩 커지는 오름차순
num3 = [1, 4, 6, 8] # 오름차순
print(set(str))  # {'a', 'b', 'c'}
print(set(num1))  # {1, 90, 3, 6}
print(set(num2))  # {1, 2, 3, 4}
print(set(num3))  # {8, 1, 4, 6}

하지만 num2처럼 1씩 커지는 리스트이면 set으로 만들어도 순차적으로 나옵니다.

풀이1

def solution(n, lost, reserve):
    
    # 여분 있고, 도난 당한 학생 제외
    lost_only = set(lost) - set(reserve)
    reserve_only = set(reserve) - set(lost)
    
    # 왼쪽부터 순서대로 여분을 넘긴다
    for r in reserve_only:
        if r-1 in lost_only:
            lost_only.remove(r-1)
        elif r+1 in lost_only:
            lost_only.remove(r+1)
            
    return n - len(lost_only)

set으로 바꿔도 학생 번호가 순서대로 나오기 때문에 가능한 풀이입니다. 만약 아래 같은 상황에서 무작위로 set이 넘겨져서, for문에서 3이 먼저 여분을 준다면 4는 체육복을 받지 못하고 끝나게 됩니다.

풀이2

reserve_only = [r for r in reserve if r not in lost]
lost_only = [l for l in lost if l not in reserve]

나머지 과정은 똑같은데, set 대신 for와 if로 중복을 제외합니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함