프로그래머스 기능개발 문제풀이

김하영·2023년 3월 15일
0

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

사용 자료구조: 큐

프로그래스에 우선순위가 있어서 배열의 앞에 위치한 프로그래스가 배포되고 나서야 뒤의 프로그래스가 배포할 수 있다는 규칙이 있기때문에 큐를 썼다. 먼저 들어간 데이터가 먼저 처리되어야하는 FIFO이므로!


찾아낸 규칙

작업에 걸리는 날을 따로 큐에 저장한다.
그리고 현재 큐에 있는 값보다 작은 값은 함께 poll()하면서 cnt를 증가시켜준다. 이는 프로그래스를 배포할 때 우선순위가 있으므로 앞의 작업보다 뒤의 작업이 적게 걸려도 앞 작업이 완료될 때 함께 배포되기 때문이다.
cnt를 모아서 int[]배열로 리턴한다.


코드설명

프로그래스 별로 걸리는 날을 저장할 큐를 선언한다.

일단 100에서 프로그래스의 값을 빼서 작업량이 얼마나 남았는지를 remain변수에 저장한다.

그리고 걸리는 날을 계산하기 위해 remain을 speed로 나눠준다. 이때 결과가 100을 채우거나 넘어야 완료하는 것이기 때문에 값을 올림해준다. 그렇게 얻은 걸리는 날을 큐에 넣어준다.

큐의 가장 앞의 값을 기준으로 삼아(flag 변수) 그 값보다 작으면 cnt변수(한번에 배포하는 프로그래스 갯수)를 증가시키며 poll()한다.(프로그래스를 배포할 때 우선순위가 있으므로 앞의 프로그래스보다 뒤의 프로그래스가 적게 걸려도 앞의 프로그래스가 완료될때 함께 배포된다.)

그리고 함수의 리턴형식을 맞춰주기 위해 cnt를 저장하고 있던 result ArrayList를 int[]로 바꿔준다.

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

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {
        int[] answer;
        ArrayList<Integer> result = new ArrayList<>();
        int remain = 0;
        int takenDay = 0;
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i<progresses.length; i++){
            remain = 100 - progresses[i];
            takenDay = (int) Math.ceil((double) remain/speeds[i]);
            queue.offer(takenDay);
        }
        int flag = queue.poll();
        int cnt = 1;
        while(!queue.isEmpty()){
            if(queue.peek() <= flag){
                cnt++;
                queue.poll();
            } else{
                result.add(cnt);
                flag = queue.poll();
                cnt = 1;
            }
        }
        result.add(cnt);


        // Arraylist를 int[]로 바꿔주는 부분
        answer = result.stream().mapToInt(i->i).toArray();

        return answer;
    }

    public static void main(String[] args) {
        new Solution().solution(new int[]{93, 30, 55},new int[]{1, 30, 5});
    }
}

시행착오 및 교훈

ArrayList를 int[]로 받는 법을 매번 까먹는다..!
두번째 방법에서는 stream연산이 저절로 int로 unboxing 해준다. 스트림을 적절하게 사용하면 코드가 간결해진다는 사실을 다시한번 더 느낀다. 또 자바는 자료형을 맞춰주는게 까다롭다고 생각한다(Integer, int 박싱 언박싱 등등). 이건 다 안정성이라는 장점을 위한 거겠지만! 어서 익숙해지고 싶다!


ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// 1
int[] arr = new int[list.size()];
for(int i=0; i<list.size(); i++){
	arr[i] = list.get(i);
}
// 2
arr = list.stream().mapToInt(i->i).toArray();
profile
백엔드 개발자로 일하고 싶어요 제발

0개의 댓글