- 첫 풀이 및 정답풀이
이 문제를 간단하게 요약해보자면, 기능을 개발을 완료하는 수치가 100일 때, 미완성된 기능의 개발 정도를 progress배열에 담아 전달해준다. 이 기능들은 진행률이 100이 되면 기능을 배포할 수 있게 된다. 이때, 각 기능을 하루에 개발할 수 있는 속도가 speeds에 담아 전달받는다. 각 기능은 이 speeds의 수치만큼 하루에 진행된다.
위의 내용을 통해 구할 수 있는 식은 각 기능을 개발 완료하는 데 걸리는 시간이다. (100 - 각 진행률) / 기능의 개발속도 를 통해 100이 되는 일 수를 구할 수 있는데 이때, 나누어 떨어지지 않는 일 수는 +1을 해주는 것을 잊으면 안 된다.
이렇게 구한 각 기능의 개발이 완료되는 일 수를 큐에 삽입한다. 큐를 사용한 이유는 앞선 개발이 완료되지 않으면 나중에 개발하는 기능이 먼저 완료되더라도 배포될 수 없다는 특징이 FIFO 구조와 일치하기 때문이다.
큐에 담긴 각 기능의 개발 일 수를 비교해 간다. 먼저 개발한 기능의 개발일 수 >= 나중에 개발한 기능의 개발일 수인 경우만 고려해 배포하는 기능의 수를 카운트해준다. 단, 주의해야 할 점은 개발일 수가 적은 나중에 개발한 기능들이 다수 존재할 수 있기 때문에, 비교 값은 항상 가장 큰 값을 기준으로 해야 한다.
(본인이 생각하지 못한 테스트 케이스로, 예를 들어 개발의 완료 기간이 98, 96, 98인 경우 98이 동일하므로 배포 수가 증가해야 하지만, 비교 기준이 바로 앞의 기능으로 고정되어 있다면 고려할 수 없게 된다.)
import java.util.Queue;
import java.util.LinkedList;
import java.util.ArrayList;
class Solution {
public ArrayList<Integer> solution(int[] progresses, int[] speeds) {
// 1. 정답을 담을 ArrayList.
ArrayList<Integer> answer = new ArrayList<>();
// 2. 개발 일 수를 담을 days배열.
int[] days = new int[progresses.length];
// 3. 큐 자료구조 이용.
Queue<Integer> queue = new LinkedList<>();
// 4. 각 기능의 개발일 수 계산.
for(int i = 0; i<days.length;i++){
days[i] = (100-progresses[i]) % speeds[i] == 0 ? (100-progresses[i]) / speeds[i] : ((100-progresses[i]) / speeds[i])+1;
// 4-1. 큐에 삽입.
queue.offer(days[i]);
}
// 5. 큐가 빌 때 까지 반복.
while(!queue.isEmpty()){
// 6. 기능의 수, 1개부터
int cnt = 1;
int num = queue.poll();
// 7. 비교할 기능이 존재하며, 나중에 개발된 기능의 개발일 수 <= 먼저 개발 된 기능의 개발일 수인 경우
while(queue.peek() != null && queue.peek() <= num){
// 7-1. 가장 큰 값을 다시 기준으로 하고 배포할 수 있는 기능의 수 증가.
int temp = queue.poll();
cnt++;
num = temp<=num ? num : temp;
}
// 8. 배포가능한 기능의 수를 ArrayList에 담는다.
answer.add(cnt);
}
return answer;
}
}