알고리즘 공부
[프로그래머스] 기능개발 - JAVA
Developer KTU
2024. 8. 10. 16:02
반응형
스택 및 큐를 사용하여 푸는 문제이다. 가장 먼저 들어온 작업이 먼저 배포되어야 하므로, 큐(Queue)를 사용하는것이 올바르다. 나에겐 전형적인 막히는 문제였다. 머리로는 큰 풀이로직이 생각났지만, 디테일한 로직이 생각나지 않아 1시간 고민끝에 답안을 보고 말았다.
<막혔던 부분>
해당 작업의 현재 완수율 배열과 하루마다 수행되는 수행률 배열을 가지고 해당 작업소요일수를 구하고 큐에 offer하는데 까진 성공했다. 하지만 이 큐를 가지고 현재 작업일수보다 작은 작업들을 count하고, 현재 작업일수보다 큰 작업들을 다시 count하는 로직을 구현해내지 못했다.
<정답 코드>
public static int[] solution(int[] progresses, int[] speeds){
int[] answer = {};
// 배포 작업들을 담을 배포큐 선언.
Queue<Integer> deployQueue = new LinkedList<>();
// 가변길이의 답안을 담기 위해 ArrayList 선언.
List<Integer> arr = new ArrayList<>();
// 각 작업의 100% 도달 일수를 구함
for(int i = 0; i < progresses.length; i++){
// 작업소요 시간
int pgrsDay = 0;
// 하루 작업 수행률이 100%와 딱 맞아떨어지는 경우는 몫을 그대로 초기화
if((100 - progresses[i]) % speeds[i] == 0){
pgrsDay = (100 - progresses[i]) / speeds[i];
// 해당 작업의 총 소요일수를 큐에 담음
deployQueue.offer(pgrsDay);
}else{
// 하루 작업 수행률이 100%와 맞아 떨이지지 않고 나머지가 생기는 경우 + 1일을 더해줌
// 예를 들어 30% 완수되어 있고 하루에 30%씩 완수되는 경우는 2일째는 90%이므로 3일째 나머지 10%를 완수해야함.
pgrsDay = (100 - progresses[i]) / speeds[i] + 1;
// 해당 작업의 총 소요일수를 큐에 담음
deployQueue.offer(pgrsDay);
}
}
/* 여기서부터 막힘 */
// 큐가 비어있지 않을때까지 loop
while(!deployQueue.isEmpty()){
// 배포 작업 갯수
int pgrsCount = 0;
// 배포 했으므로 배포큐에서 poll() 후 작업일수를 가져온다.
int nowPrgsDay = deployQueue.poll();
// 현재 작업은 무조거 배포해야하므로 +1한다.
pgrsCount++;
// 큐가 비어있지 않을때 가장 아래의 작업일수를 비교
// 현재 작업소요일수가 다음 작업들의 총 소요일수보다 크면 같이 배포해야 하므로 작업갯수 + 1함.
while(!deployQueue.isEmpty() && deployQueue.peek() <= nowPrgsDay){
// 현재 작업과 같이 배포해야하므로 배포작업개수 +1
pgrsCount++;
// 배포했으므로 poll()
deployQueue.poll();
}
arr.add(pgrsCount);
}
/* 여기서부터 막힘 끝 */
// 가변길이의 정답 리스트를 int[] 형으로 변환
answer = arr.stream().mapToInt(Integer::new).toArray();
return answer;
}
내가 생각한 로직을 코드로 옮기는 연습과 수학적 로직을 코드로 옮기는 연습을 더 해야겠다. 흠.. 프로그래머스 Lv1 문제나 백준 수학 문제들을 더 풀어봐야겠다!
반응형