Algorithm/프로그래머스

[프로그래머스/Python] 체육복 - Level1

poppy 2021. 6. 12. 15:03
반응형

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

 

코딩테스트 연습 - 체육복

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

programmers.co.kr

def solution(n, lost, reserve):
    student = [0] * (n+2)
    answer = 0
    
    # 여분 체육복 있는 사람은 값 1로 만들기
    for r in reserve:
        student[r] += 1
    
    # 체육복을 안가지고 온 사람은 값 -1로 만들기
    for l in lost:
        student[l] -= 1
        
    # 체육복을 입을 수 있는 사람의 최댓값 구하기
    for i in range(1, n+1):
        if student[i] == -1: # 체육복을 가지고 오지 않은 경우
            if student[i-1] == 1: # 앞 사람에게 빌릴 수 있는 경우
                student[i-1] -= 1
                student[i] += 1
            elif student[i+1] == 1: # 뒷 사람에게 빌릴 수 있는 경우
                student[i+1] -= 1
                student[i] += 1
        
        # 체육복이 있는 사람 수 세기
        if student[i] != -1:
            answer += 1
                
    return answer

student = [0] * (n+2) 을 한 이유는 앞 사람과 뒷 사람의 값에 접근할 때 인덱스 에러가 발생할 수 있어서 배열의 크기를 n이 아닌 n+2로 생성하였다. reserve 리스트를 돌면서 체육복이 있는 사람의 값은 1로 만들어 주고, lost 리스트를 돌면서 체육복이 없는 사람의 값은 -1로 만들어준다. for문으로 전체 배열을 돌면서 최대한 체육복을 많이 입을 수 있도록 빌려주는 과정을 거친다. 체육복이 없는 사람이라면 앞 사람이나 뒷 사람에게 빌릴 수 있는지 확인하고 빌릴 수 있으면 해당 사람의 값을 +1하여 0으로 만들어주고 빌려준 사람의 값은 -1하여 0으로 만들어준다. if문을 통해 체육복 있는 사람의 수를 세는데 -1은 체육복이 없는 사람이므로 -1이 아닐 때만 answer에 +1을 해준다.

 

문제를 풀면서도 나보다 간단한 코드가 있을 것 같다는 생각을 했다. 역시 다른 사람들의 풀이를 보니 나보다 훨씬 간단했다. "여벌의 체육복이 있는 학생도 도난당할 수 있다" 라는 말에 유의하여 미리 reserve와 lost에 중복된 값을 제거해준 것이 놀라웠다. 문제를 자세히 보지 않아 이런 조건이 있는지 몰랐다...

def solution(n, lost, reserve): 
    reser_del = set(reserve)-set(lost) 
    lost_del = set(lost)-set(reserve) 
    
    for i in reser_del: 
        if i-1 in lost_del: 
            lost_del.remove(i-1) 
        elif i+1 in lost_del: 
            lost_del.remove(i+1) 
            
    return n-len(lost_del)
반응형