가장 먼저 각 배열을 HashSet으로 만들었다. 문제를 깊게 들어가봤을 때, 배열을 그대로 놓고 푼다면 반복문마다 배열을 계속 뒤지는 상황이 발생할 것이라 판단해서 차라리 처음에 한번 쭉 배열을 돌아, 추후 필요한 값을 찾을 때 시간복잡도가 소요되지 않도록 만들었다.
1번 학생부터 n번 학생까지 반복문을 돌며 각 학생이 체육수업에 참여할 수 있는지 판단하고, 참여할 수 있다면 변수 count를 증가시켜주는 방식으로 설계했다.
가장 먼저, 반복문을 돌 때 체육복을 잃어버리지 않은 학생을 만나면 count를 증가시켜줬다.
두 번째로, 체육복을 잃어버린 학생을 만났다면 다음과 같은 순서대로 체육복을 빌릴 수 있는지 확인했다. [앞번호 학생 --> 본인 --> 뒷번호 학생], 빌릴 수 있다면 count를 증가시켜주고 해당 학생에게 빌려준 여유분은 뒷사람이 중복해서 빌리는 것을 방지하기 위해 삭제한다.
앞번호 학생부터 빌리고 이후 순차적으로 본인, 뒷번호 학생으로 나아가는게 가장 최선의 방식이라고 판단했다. --> 그리디(탐욕법)
아래는 해당 과정의 소스코드이다
import java.util.Set;
import java.util.HashSet;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
int count = 0;
Set<Integer> set_lost = new HashSet<>();
Set<Integer> set_reserve = new HashSet<>();
for(int res : reserve) {
set_reserve.add(res);
}
for(int los : lost) {
set_lost.add(los);
} // HashSet 각각 선언
for(int i = 1; i <= n; i++) {
if(!set_lost.contains(i)) count++;
else if(set_reserve.contains(i - 1)) count++;
else if(set_reserve.contains(i)) {
count++;
set_reserve.remove(i);
}
else if(set_reserve.contains(i + 1)) {
count++;
set_reserve.remove(i + 1);
}
}
return count;
}
}
이렇게 했을 때 30여개의 테스트 케이스 중 3개를 통과하지 못했다.
본문의 내용 중 체육복을 잃어버린 사람이 여유분을 가지고 있다면 해당 학생은 본인의 체육복을 단 한개만 가지고 있다고 간주한다는 문장을 보고, 첫 번째 코드는 방금 언급한 내용을 위반한다는 사실을 알게되어 메인 for문을 수정했다. 아래는 수정한 내용이다.