출처: 프로그래머스 코딩테스트 체육복 (Greedy) 1번째 문제
(https://programmers.co.kr/learn/courses/30/lessons/42862)
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Collections;
import java.util.stream.Stream;
class Solution {
public static int solution(int n, int[] lost, int[] reserve) {
Integer answer = null;
int count = 0;
// 1.
List<Integer> losts = Arrays.stream(lost).boxed().collect(Collectors.toList());
List<Integer> reserves = Arrays.stream(reserve).boxed().collect(Collectors.toList());
// 2.
List<Integer> duplicatedElements = getDuplicates(
Stream.concat(losts.stream(),reserves.stream()).collect(Collectors.toList())
);
losts = losts.stream().filter( p -> !duplicatedElements.contains(p)).collect(Collectors.toList());
reserves = reserves.stream().filter( p -> !duplicatedElements.contains(p)).collect(Collectors.toList());
// 3.
for ( final Integer l : losts ) {
// 6.
if ( reserves.size() == 0 ) break;
// 4.
final Integer front = l - 1;
final Integer back = l + 1;
final Integer target = reserves.stream()
.filter( p -> p.equals(front) || p.equals(back) )
.findFirst()
.orElse(null);
// 5.
if ( target != null ) {
reserves.remove(target);
count++;
}
}
// 7.
answer = n - (losts.size() - count);
return answer;
}
private static <T> List<T> getDuplicates(List<T> list) {
return list.stream()
.filter( p -> Collections.frequency(list,p) > 1)
.distinct()
.collect(Collectors.toList());
}
}
Stream api를 써서 처리하고 싶어 컬렉션 객체로 변환했는데 먼가 소스가 너무 지저분해진 것 같다. 그리고 소스를 짜고 난 후 깨달았는데 중복값은 Set 자료구조를 이용하면 더 좋았을 것 같다. 더 신경써서 코딩해야겠다.