코딩테스트 연습 > 탐욕법(Greedy) > 체육복https://school.programmers.co.kr/learn/courses/30/lessons/42862
전체 학생의 수 n, 체육복 도난 당한 학생 번호 배열 lost, 여벌 체육복 학생 번호 배열 reserver가 있을 때, 여벌 체육복을 가져온 학생이 도난 당한 학생에게 체육복을 빌려줄 수 있을 때, 체육복을 가진 학생이 최대가 되는 수를 return 하라.
여벌 체육복을 가진 학생이 도난을 당할 수 있다. 이 때, 도난 당한 체육복 수는 1벌로 고정한다.

HashSet을 이용하여 도난당한 학생들, 여벌을 가져온 학생들을 저장한 뒤, 여벌을 가졌지만 도난 당한 학생들 여벌 가져온 학생들 저장한 HashSet에서 제거한다.
이 후, 여벌이 있는 학생 HashSet의 저장 된 index+-1 위치의 학생이 체육복을 잃어버린 학생 Hashset에 저장 된 경우 이를 제거한다.
마지막으로 결과는 n-체육복 잃어버린 학생 HashSet의 size를 뺀 값이다.
import java.util.*;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
HashSet<Integer> hs = new HashSet<>();
HashSet<Integer> hs_l = new HashSet<>();
Arrays.sort(lost);
Arrays.sort(reserve);
for(int i : reserve){
hs.add(i);
}
for(int j : lost){
if(hs.contains(j)) {
hs.remove(j);
}else{
hs_l.add(j);
}
}
for(int k : hs){
if(hs_l.contains(k-1)){
hs_l.remove(k-1);
}else if(hs_l.contains(k+1)){
hs_l.remove(k+1);
}
}
return n-hs_l.size();
}
}
Reivew(배열)
import java.util.*;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
int answer = 0;
// lost, reserve 정렬
Arrays.sort(lost);
Arrays.sort(reserve);
// lost 학생 중 reserve 포함 -> lost, reserve에서 제거
for(int i = 0; i< lost.length; i++){
for(int j = 0; j<reserve.length; j++){
if(lost[i] == reserve[j]){
lost[i] = -1;
reserve[j] = -1;
break;
}
}
}
// reserve 배열 순회 +-1 하면서 lost 포함 되어 있으면 lost에서 삭제
for(int i = 0; i<reserve.length; i++){
for(int j = 0; j<lost.length; j++){
if(lost[j] == reserve[i] -1 || lost[j] == reserve[i] + 1) {
lost[j] = -1;
reserve[i] = -1;
}
}
}
// lost 학생 수 반환
for(int k : lost){
if(k > 0) answer--;
}
return answer + n;
}
}
그리디 문제를 처음 풀어서 꽤나 막히는 부분이 있었으나 여벌을 가진 학생, 잃어버린 학생을 각각 HashSet에 저장하여 풀어보니 어렵지 않았다.
배열로도 풀 수 있다는 것을 알았다.
배열로 푸니 공간적인 낭비 없이 풀 수 있었다.

Review
