[프로그래머스/Level1] 체육복

SeokHyun·2022년 7월 4일
0

프로그래머스

목록 보기
16/32

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42862

문제 접근

그리디는 너무 오랜만에 풀어봐서 처음에 쉽다고 생각했는데 오래 걸렸다.

이번에도 제약 사항 중 놓친 케이스가 있었다...

어쨋든 핵심은 다음과 같다.

  1. 여벌옷을 가져왔는데 도난당한 경우를 먼저 제거
  2. 두 가지 케이스로 분류해서 카운팅
    • 앞에서 빌리고 없으면 뒤에서 빌리는 경우
    • 뒤에서 빌리고 없으면 앞에서 빌리는 경우

소스 코드

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);
    }
}
profile
SI를 넘어 백엔드 엔지니어를 향하여

0개의 댓글