728x90
문제
문제 분석
여분이 있는 학생은 앞, 뒤 학생에게만 빌려줄 수 있고, 여분이 있어도 도난 당했을 수 있다는 전제를 처리를 하고,
빌려주는 로직을 짜면 될 거 같다.
알고리즘
- Set의 차집합을 활용하여 lost와 reserve 배열을 비교하여 여유분을 도둑맞은 처리를 해 준다.
- reserve의 값을 가지고 lost를 순회하면서 빌려줄 수 있는지 확인, 가능하다면 삭제처리(대여)를 한다
- 총 인원 수와 lost의 배열 개수를 빼서 리턴한다.
코드
import Foundation
func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
//여벌을 가져왔지만 도난당할 수 있으니 그거에 대한 전처리 먼저한다.
var losts = Set(lost).subtracting(reserve).sorted()
let reserves = Set(reserve).subtracting(lost).sorted()
//sorted()로 다시 뽑아준건, Set은 무질서 컬렉션이라 순회작업에 적합하지 않다.
//여벌 옷이 있는 친구는 앞 뒤 사람만 빌려줄 수 있다.
for item in reserves {
for index in 0..<losts.count {
if losts[index] == item-1 {
losts.remove(at: index)
break;
}
else if losts[index] == item+1{
losts.remove(at: index)
break;
}
}
}
return n-losts.count
}
문제 해결 중 어려웠던 것
집합을 생각해내서 제외 시키는 데 문제는 없었지만, 계속 17,18,19 테스트 케이스가 틀렸다고 나왔었다.
알고보니 Set은 unordered collection으로 순서가 보장되지 않은 collection이여서 오류가 나온거 같다...
sorted()를 사용해서 다시 배열로 반환시켜주니 문제없이 원래 로직대로 해결 할 수 있었다!
다른방식
import Foundation
func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
// 체육복애 여별의 수를 저장하는 배열, 초기값은 0
var clothCount = Array(repeating: 0, count: n)
// 체육복을 읽어 버린 경우 -1로 설정
for i in lost { clothCount[i-1] = -1 }
// 여벌 체육복이 있는 경우 1로 설정
for j in reserve { clothCount[j-1] = 1 }
// 전체 학생의 여벌 체육복 배열을 인덱스와 값을 하나씩 비교하면 순회
for (index, k) in clothCount.enumerated() {
// 현재 학생이 체육복을 읽어 버린 경우
if k == -1 {
// 앞의 학생이 여벌 체육복이 있는지(== 1) 비교한 후 있으면 빌림
if index > 0 && clothCount[index-1] == 1 {
clothCount[index] += 1
clothCount[index-1] += -1
}
// 뒤의 학생이 여벌 체육복이 있는지 비교한 후 있으면 빌림
else if index < clothCount.count - 1 &&
clothCount[index+1] == 1 {
clothCount[index] += 1
clothCount[index+1] += -1
}
}
}
// 최소 체육복이 있는 경우(>= 0)의 학생의 수를 최종 반한
return clothCount.filter{ $0 >= 0 }.count
}
- 전체 학생의 체육복 개수를 관리하는 변수 만들기관리하는 변수를 만들고, 잃어버린 경우, 여벌이 있는 경우에 값을 변경해주면서 해결하는 방식이였다.
- 이렇게 해결 했어도 금방 끝날 문제였던거 같다.
728x90