https://programmers.co.kr/learn/courses/30/lessons/42862?language=swift
체육복을 잃어버린 학생들에게 인접한 학생들이 체육복 여벌을 나누어 줄 수 있을 때 몇 명의 학생들이 체육 수업을 들을 수 있는지 파악하는 문제이다.
눈여겨 봐야 할 부분은 "내가 여벌을 가져왔더라도 나 또한 체육복을 잃어버릴 수 있다는 것"이다. 실제로 보면 뭔가 웃긴 상황...
이 경우에는 남에게 빌려주지 못하고 본인이 입어야 한다. 즉, 사전에 걸러줘야할 케이스이라는 것이다.
그리고 인접한 학생이라고 하면 +1, -1에 해당하는 학생을 말하는 것 이기에 여벌을 가지고 있는 학생은 2명의 선택지를 가지고 있는 것이다.
대략 구현해야하는 것들을 먼저 순서대로 봐보자.
1. 내가 가져오고, 내가 잃어버린 경우들을 lost, reserve에서 제거해주자. 세어 줄 필요가 없음
2. 빌려줄 수 있는 경우를 count에 체크한다. (초기 count = 잃어버린 학생 수)
3-a. 여벌을 가진 학생이 이미 다른 학생에게 빌려준 것은 아닌지 확인
3-b. 잃어버린 학생을 기준으로 +1, -1에 해당하는 여벌을 가진 학생이 있는지 확인
3-b-1. 빌려줄 수 있는 상황이기에 잃어버린 학생에게 주고 빌려줬다는 표기(=0) 및 count -= 1 후 해당 case 종료
(count -= 1은 잃어버린 학생 수를 줄이는 것이기에, 구제해준 것이라고 봐도 됨!)
4. 체육 수업을 들을 수 있는 총 학생 수는 다음과 같다. 총 학생 수 - 잃어버린 학생 수 + 여벌
바로 코드로 고고고
import Foundation
func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
// 여벌을 가지고 있는 학생 중 잃어버린 경우가 있는 지 먼저 파악해야함
// 왜냐, 빌려주지 못하고 자기가 입어야하기 때문
var realReserve = reserve.filter { !lost.contains($0) }
var realLost = lost.filter { !reserve.contains($0) }
var count = realLost.count
if count == 0 { return n }
for i in 0..<realLost.count {
for j in 0..<realReserve.count {
// 이미 빌려준 경우 다음 여벌로
if realReserve[j] == 0 {
continue
// 잃어버린 학생이 여벌을 갖고 있는 학생의 앞 뒷 번호 학생 중 하나일 경우
} else if realLost[i] == realReserve[j] - 1 || realLost[i] == realReserve[j] + 1 {
// 빌려준 경우 0으로 표기
realReserve[j] = 0
// 잃어버린 학생 수에서 한 명씩 구제
count -= 1
// 다음 잃어버린 학생을 기준으로
break
}
}
}
// 전체 학생 수 - (잃어버린 학생 수 + 커버 가능한 개수)
return n - count
}
자세한 내용은 주석을 참고하면 이해를 도울 수 있을 것 같다.
빌려줄 수 있는 범위와, 빌려준 후 처리, 제한사항을 고려하면 그나마 쉽게 해결할 수 있는 문제!
끄읕