문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42862
그리디는 너무 오랜만에 풀어봐서 처음에 쉽다고 생각했는데 오래 걸렸다.
이번에도 제약 사항 중 놓친 케이스가 있었다...
어쨋든 핵심은 다음과 같다.
import java.util.*;
import java.util.stream.*;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
List<Integer> lostList = new ArrayList<>();
List<Integer> frontReserveList = new ArrayList<>(); //앞에서 빌리고 없으면 뒤에서 빌리는 경우
List<Integer> backReserveList = new ArrayList<>(); //뒤에서 빌리고 없으면 앞에서 빌리는 경우
//체육복 남은 학생 리스트
for (int i : reserve) {
frontReserveList.add(i);
backReserveList.add(i);
}
//체육복 남았는데 도난당한 경우 제외
for (int i : lost) {
boolean isSame = Arrays.stream(reserve)
.filter(reserveStd -> reserveStd == i)
.findFirst()
.isPresent();
if (isSame) {
frontReserveList.remove((Integer) i);
backReserveList.remove((Integer) i);
} else {
lostList.add(i);
}
}
int frontLostCount = lostList.size();
int backLostCount = lostList.size();
for (int student : lostList) {
Optional<Integer> frontBorrow = frontReserveList.stream()
.filter(id -> (id - 1) == student)
.findFirst();
Optional<Integer> backBorrow = frontReserveList.stream()
.filter(id -> (id + 1) == student)
.findFirst();
//앞에서 먼저 빌리고 없으면 뒤에서 빌리는 경우
if (frontBorrow.isPresent()) {
frontReserveList.remove(frontBorrow.get());
frontLostCount--;
} else if (backBorrow.isPresent()) {
frontReserveList.remove(backBorrow.get());
frontLostCount--;
}
frontBorrow = backReserveList.stream()
.filter(id -> (id - 1) == student)
.findFirst();
backBorrow = backReserveList.stream()
.filter(id -> (id + 1) == student)
.findFirst();
//뒤에서 먼저 빌리고 없으면 앞에서 빌리는 경우
if (backBorrow.isPresent()) {
backReserveList.remove(backBorrow.get());
backLostCount--;
} else if (frontBorrow.isPresent()) {
backReserveList.remove(frontBorrow.get());
backLostCount--;
}
}
//두 개의 케이스 중 더 많이 빌린 경우로 계산
return n - Math.min(frontLostCount, backLostCount);
}
}