알고리즘 유형 : 그리디
풀이 참고 없이 스스로 풀었나요? : X
https://programmers.co.kr/learn/courses/30/lessons/42862
def solution(n, lost, reserve):
answer = 0
inven = [1]*(n+1)
for s in lost:
inven[s] -= 1
for r in reserve:
inven[r] += 1
for i in range(1, n+1):
if inven[i] == 0:
if inven[i-1] == 2:
inven[i] += 1
inven[i-1] -= 1
elif i < n and inven[i+1] == 2:
inven[i] += 1
inven[i+1] -= 1
for e in inven[1:]:
if e != 0:
answer += 1
return answer
def solution(n, lost, reserve):
answer = 0
lost_set = set(lost) - set(reserve)
reserve_set = set(reserve) - set(lost)
for s in reserve_set:
if s-1 in lost_set:
lost_set.remove(s-1)
elif s+1 in lost_set:
lost_set.remove(s+1)
answer = n - len(lost_set)
return answer
풀이 요약
먼저 체육복 여벌을 가지고 있는데 본인 체육복을 도난당한 학생을 생각해보자.
이 경우 여벌 체육복을 본인이 써야하므로, 이 때 이 학생은 체육수업을 들을 수 있고 여벌 체육복은 없는 상태가 된다.
즉, lost와 reserve 두 리스트에서 이 학생은 제외되어야한다. 이를 위해 set의 차집합을 수행한다.
그 외의 경우를 생각해보자.
아래 테스트 케이스를 보자.
n = 5, lost = [2,4], reserve = [3, 5]
만약 3이 4한테 체육복을 주면, 2는 아무한테도 체육복을 못 받는다. 반면 3이 2한테 체육복을 주면, 4는 5한테 체육복을 받을 수 있다.
이를 일반화해서 생각하면, 여분을 가진 학생은 자신보다 작은 학생부터 우선적으로 체육복을 주려고 해야한다. (reserve 오름차순 정렬 기준)
reserve의 가장 작은 값의 학생부터 순회하면서 체육복 지급을 계산해본다고 하면, 가장 작은 값의 학생 n이 n-1에게 체육복을 줘버린다고 해도, 위 예제의 한 경우처럼 손해보는 경우가 없다. 만약 안 주게되면 n-1에게 체육복을 줄 학생이 반드시 없기 때문이다.
배운 점, 어려웠던 점