[Java/자바] 프로그래머스 Lv2 - 기능개발 (Queue)

문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고,

이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때

각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

 

제한 사항
  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

 

입출력 예
progresses speeds return
[93, 30, 55] [1, 30, 5] [2, 1]
[95, 90, 99, 99, 80, 99] [1, 1, 1, 1, 1, 1] [1, 3, 2]

 


Solution.java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;


public class 기능개발 {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(solution(new int[]{93, 30, 55}, new int[]{1, 30, 5})));
        System.out.println(Arrays.toString(solution(new int[]{95, 90, 99, 99, 80, 99}, new int[]{1, 1, 1, 1, 1, 1})));
    }

    public static int[] solution(int[] progresses, int[] speeds) {
        Queue<Integer> workDays = getWorkDays(progresses, speeds);
        int[] answer = getDistributionCount(workDays);

        return answer;
    }

    // 작업 일 수 구하는 함수
    private static Queue<Integer> getWorkDays(int[] progresses, int[] speeds) {
        int success = 0;
        Queue<Integer> workDays = new LinkedList<>();

        for (int i = 0; i < progresses.length; i++) {
            int count = 0;
            success = progresses[i];

            while (success < 100) {
                success += speeds[i];
                count++;
            }
            workDays.add(count);
        }
        return workDays;
    }

    // 배포가능 한 기능 수 구하는 함수
    private static int[] getDistributionCount(Queue<Integer> workDays) {
        List<Integer> answer = new ArrayList<>();

        while (!workDays.isEmpty()) {
            int currentWork = workDays.poll();
            int function = 1;

            // 작업 시간이 같은 경우에도 같은 날에 배포가 되므로 ">="
            while (!workDays.isEmpty() && currentWork >= workDays.peek()) {
                function++;
                workDays.poll();
            }
            answer.add(function);
        }

        // List를 int[] 배열로 변환
        return answer.stream().mapToInt(Integer::intValue).toArray();
    }
}

 

이번 코드는 좀더 이해하기 쉽도록 기능별로 함수를 분리하여 만들었습니다.

처음에는 배열을 이용해 풀다가 다음 인덱스와 비교하는게 힘들어서 Queue로 문제를 풀었는데

Queue로 푸는 방식이 훨씬 편했던 것 같습니다.

만약 Queue에 대하 알고 싶다면 아래 포스팅을 참고하시면됩니다.

 

[Java/자바] 스택(Stack)과 큐(Queue)

스택(Stack)과 큐(Queue)를 설명하기 앞서 간단하게 알아봅시다. Stack은 LIFO(Last In First Out) 구조로 되어 있으며, 쉽게 해석하면 "후입 선출" 입니다. 즉, 마지막(최근)에 넣은 것을 먼저 뺀다는 말이죠.

hstory0208.tistory.com

 

문제 풀이
  1. progresses와 speeds로 각 작업들이 몇일이 걸리는지 구합니다. (workDays)
  2. 구한 작업 일수(workDays)의 맨 앞값과 그 다음 값을 비교합니다.
  3. 앞의 작업이 더 크다면 앞의 작업이 끝나야 뒷 작업도 배포 가능하기 때문에 function을 1 증가시키고 해당 작업을 poll로 제거합니다.

Queue의 poll과 peek에 대한 이해를 좀 더 쉽게 돕고자 그림을 첨부합니다.