본문 바로가기
Algorithme/Programmers

[프로그래머스] 야근 지수 Java

by 케로베로 2020. 10. 26.

programmers.co.kr/learn/courses/30/lessons/12927

 

코딩테스트 연습 - 야근 지수

회사원 Demi는 가끔은 야근을 하는데요, 야근을 하면 야근 피로도가 쌓입니다. 야근 피로도는 야근을 시작한 시점에서 남은 일의 작업량을 제곱하여 더한 값입니다. Demi는 N시간 동안 야근 피로도

programmers.co.kr

 

문제 요약

야근을 시작하는데 남은 일의 양은 works배열 만큼 있고, 퇴근까지 시간은 n 만큼 남아있다. 한 시간에 1의 작업량만을 해결할 수 있으며, 야근이 끝난 후의 피로도는 남은 작업들의 제곱의 합이다. 퇴근 시간이 되었을 때 남을 수 있는 가장 적은 피로도를 반환하는 함수를 만들어야 한다.

 

문제 풀이

 당연히 피로도를 줄이기 위해서는 가장 남은양이 많은 업무를 먼저 해결해 나가는 것이 옳다. 한 시간마다 남은 업무들의 남은 작업량을 구하기 위해서 우선순위 큐를 이용해 문제를 풀었다. 작업량이 많이 남은 업무를 먼저 처리 해야하기 때문에 우선 순위 큐를 만들 때에는 Compator.reverseOrder()을 사용해줬다.

 

 최대 힙에 works를 모두 넣고 n시간 동안 일을 처리해야 하기 때문에 1시간 마다 큐의 최대 값에 1의 작업량을 뺀 후 다시 넣기를 반복했다. 반복(야근)이 끝나고 남은 일들의 작업량을 제곱 후 합해줘서 피로도를 구해야하는데 여기서 filter를 이용해서 0보다 작은 값들은 제외 했다.(작업량이 모두 해결되었을 때 0 보다 작아질 수 있기 때문)

 

나의 코드

import java.util.*;

import static java.util.stream.Collectors.summingLong;
import static java.util.stream.Collectors.toList;

class 야근_지수 {
    public long solution(int n, int[] works) {
        // 우선 순위 큐 생성 후 works 를 모두 넣기
        PriorityQueue<Integer> heap = new PriorityQueue<>(Comparator.reverseOrder());
        heap.addAll(Arrays.stream(works).boxed().collect(toList()));

        // 작업량이 높은 순으로 1씩 해결
        for (int i = 0; i < n; ++i)
            heap.offer(heap.poll() - 1);

	// 남은 작업량이 0보다 큰 작업들의 제곱을 합해서 반환
        return heap.stream().filter(i -> i > 0).collect(summingLong(i -> i * i));
    }
}