📚 Problem
체육복
- 번호는 체격순 (1 ~ N)
- 바로 앞 or 바로 뒤 만 빌려주기 가능
- 여벌이 있는 학생만 체육복을 도난당한(체육복이 없는) 학생에게 빌려주기 가능
- 여벌이 있는 학생도 도난을 당할 수 있고, 이때는 여벌이 없어져 다른 학생에게 빌려줄 수 없음
- 체육수업을 들을 수 있는 학생의 최댓값 구하기
📝 Solution
- 3가지의 상태로 학생들을 구분합니다
- -1 : 체육복을 도난당해 없는 상태
- 0 : 체육복을 본인의 것만 가지고 있는 상태 (여별 X)
- 1 : 체육복을 여벌로 가지고 있는 상태 (2개)
- 학생 수와 같은 int 배열을 생성합니다 (체육복의 수를 나타내는 배열, 처음엔 모두 0 으로 초기화)
- reserve 에 있는 번호들에 해당하는 학생들의 체육복수를 1 증가시킵니다
- lost 에 있는 번호들에 해당하는 학생들의 체육복수를 1 감소시킵니다
- 체육복이 없는 학생들의 앞, 뒤를 조사하여 앞 또는 뒤에 체육복이 여벌로 있는 학생이 있다면 빌립니다
- 체육복이 없는 학생들을 제외한 학생들의 수를 카운팅한 것이 결과입니다!
public int solution(int n, int[] lost, int[] reserve){
int answer = 0;
int[] students = new int[n + 1];
reserveStd(students, reserve);
lostStd(students, lost);
borrow(n, students);
answer = countResult(n, students);
return answer;
}
💻 Code
Solution.java
public class Solution {
public int solution(int n, int[] lost, int[] reserve){
int answer = 0;
int[] students = new int[n + 1];
reserveStd(students, reserve);
lostStd(students, lost);
borrow(n, students);
answer = countResult(n, students);
return answer;
}
private void reserveStd(int[] students, int[] reserve){
for(int reserveStd : reserve)
students[reserveStd]++;
}
private void lostStd(int[] students, int[] lost){
for(int lostStd : lost)
students[lostStd]--;
}
private boolean isReserve(int suit){
return suit > 0;
}
private boolean isNoSuit(int suit){
return suit < 0;
}
private boolean withinRange(int n, int student){
return student >= 1 && student <= n;
}
private void borrowFromFront(int i, int[] students){
students[i]++;
students[i - 1]--;
}
private void borrowFromBack(int i, int[] students){
students[i]++;
students[i + 1]--;
}
private boolean isFrontReserve(int n, int i, int[] students){
return withinRange(n, i - 1) && isReserve(students[i - 1]);
}
private boolean isBackReserve(int n, int i, int[] students){
return withinRange(n, i + 1) && isReserve(students[i + 1]);
}
private void borrow(int n, int[] students){
for(int i = 1; i <= n; i++)
if(isNoSuit(students[i])){
if(isFrontReserve(n, i, students))
borrowFromFront(i, students);
else if(isBackReserve(n, i, students))
borrowFromBack(i, students);
}
}
private boolean haveSuit(int student){
return student >= 0;
}
private int countResult(int n, int[] students){
int result = 0;
for(int i = 1; i <= n; i++)
if(haveSuit(students[i]))
result++;
return result;
}
}
SolutionTest.java
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class SolutionTest {
Solution sol;
@BeforeEach
public void setSol(){
sol = new Solution();
}
@Test
public void solution_1(){
assertEquals(5, sol.solution(5, new int[]{2, 4}, new int[]{1, 3, 5}));
}
@Test
public void solution_2(){
assertEquals(4, sol.solution(5, new int[]{2, 4}, new int[]{3}));
}
@Test
public void solution_3(){
assertEquals(2, sol.solution(3, new int[]{3}, new int[]{1}));
}
}