반응형
풀이 과정
처음에는 같은 개수를 배열에 담는 문제인가? 라고 생각했다.
progresses 는 각 기능의 현재 개발 진도를 나타내는 정수 배열 [ 93, 30, 55]
speeds 는 각 기능의 개발 속도를 나타내는 정수 배열 [1, 30, 5]
각 기능은 개발 진도 100%일 때 서비스에 반영될 수 있다. 만약 진도가 93% 이고 속도가 1%인 기능은 7일이 걸리고, 진도가 30%인 기능은 3일이 걸린다.
그렇다면 어떻게 풀어야할까?
1. 각 직업의 남은 일수를 계산한다.
2. 남은 일수들을 순서대로 큐에 저장한다.
3. 큐에서 남은 일수를 하나씩 꺼내어 각 배포마다 몇 개의 기능이 배포되는지 계산한다.
import java.util.*;
class Solution {
public int[] solution(int[] progresses, int[] speeds) {
Queue<Integer> q = new LinkedList();
for(int i=0; i<progresses.length; i++){
int rest = 100 - progresses[i];
if(rest%speeds[i] == 0)
q.offer(rest/speeds[i]);
else
q.offer(rest/speeds[i]+1);
}
List<Integer> processList = new ArrayList();
int process = q.peek(), cnt = 0;
while(!q.isEmpty()){
int n = q.poll();
if(process < n){
processList.add(cnt);
cnt = 0; process = n;
}
cnt+=1;
}
processList.add(cnt);
return processList.stream().mapToInt(i -> i).toArray();
}
}
코드 풀이
Queue<Integer> q = new LinkedList();
for(int i = 0; i < progresses.length; i++){
int rest = 100 - progresses[i];
if(rest % speeds[i] == 0)
q.offer(rest / speeds[i]);
else
q.offer(rest / speeds[i] + 1);
}
- Quere 에는 남은 작업일을 저장할 큐를 생성해준다.
- for 문을 통해 각 작업의 남은 진행도를 계산하여 작업 속도로 나눠 완료까지 남은 날짜를 큐에 저장해준다.
- rest % speeds[i] == 0이면 rest / speeds[i] 값을 큐에 추가하고, 그렇지 않으면 rest / speeds[i] + 1 값을 큐에 추가한다.
List<Integer> processList = new ArrayList();
int process = q.peek(), cnt = 0;
while(!q.isEmpty()){
int n = q.poll();
if(process < n){
processList.add(cnt);
cnt = 0; process = n;
}
cnt += 1;
}
processList.add(cnt);
- List<Integer> processList = new ArrayList(); 각 배포마다 배포되는 작업 수를 저장할 리스트를 생성한다.
- int process = q.peek(), cnt = 0;: 첫 번째 작업의 남은 날짜를 process 변수에 저장하고, 배포되는 작업 수를 세기 위한 cnt 변수를 0으로 초기화 한다.
- while(!q.isEmpty()) 루프를 통해 큐에서 작업을 하나씩 꺼내어 현재 작업일(process)보다 크면 새 배포가 필요하다고 판단하여 cnt 값을 processList에 추가합니다. 이후 cnt를 초기화하고 process를 갱신한다.
- cnt 값을 1씩 증가시켜 배포되는 작업 수를 세어준다.
- 큐가 비어있으면 마지막 cnt 값을 processList에 추가한다.
// 스트림과 람다를 사용하지 않고 List<Integer>를 int[]로 변환하는 부분
int[] resultArray = new int[processList.size()];
for (int i = 0; i < processList.size(); i++) {
resultArray[i] = processList.get(i);
}
return resultArray;
// 스트림, 람다 사용
processList.stream().mapToInt(i -> i).toArray();
- 마지막으로 return할때 남을 일자를 int형으로 전환하는데 코드가 지져분해져서 스트림과 람다를 이용해서 마무리를 해보았다.
다른 사람 코드
import java.util.*;
class Solution {
public int[] solution(int[] progresses, int[] speeds) {
Queue<Integer> q = new LinkedList<>();
List<Integer> answerList = new ArrayList<>();
for (int i = 0; i < speeds.length; i++) {
double remain = (100 - progresses[i]) / (double) speeds[i];
int date = (int) Math.ceil(remain);
if (!q.isEmpty() && q.peek() < date) {
answerList.add(q.size());
q.clear();
}
q.offer(date);
}
answerList.add(q.size());
int[] answer = new int[answerList.size()];
for (int i = 0; i < answer.length; i++) {
answer[i] = answerList.get(i);
}
return answer;
}
}
정리
이번 문제에서 중요하게 봐야할께 무엇일까? 간단하게 생각하면 완료까지 걸리는 일수를 정확하게 계산하는게 중요하다.
(남은 진도/ 속도) 로 남은 일을 구할 수 있지만, 나머지가 발생하면 하루 더 필요하기 때문에 (남은 진도 + 속도 - 1) /속도 를 사용해야한다. 큐를 이용하여 작업의 완료 일수를 순서대로 처리하기 위해 큐를 이용하고 각 배포마다 몇 개의 기능이 배포되는지를 배열로 반환해야한다. 그래야 정확히 계산이 가능하다.