프로그래머스 - 기능개발
카테고리: 스택/큐
레벨: 2
언어: Java
문제 이해하기
입출력 예시
[93, 30, 55]를 가지고 문제를 이해해 보자.
먼저 그림을 그려보면서 이해를 해보면 1칸에 하루가 걸린다고 가정을 해보자.
기능 A를 완료하는 데 걸리는 기간은 7일, 기능 B는 3일, 기능 C는 9일이 걸린다.
하지만 문제에서 나왔던 것처럼 기능 B가 A보다 빨리 끝났다 하더라도 기능 A가 완료되기 전까지 기능 B는 배포가 불가능하다.
7일이 돼서 기능 A가 완료되었다고 하면 먼저 끝난 기능 B와 같이 배포하게 된다. 나머지 기능 C는 9일이나 걸리기 때문에 해당 기능이 완료되면 알아서 배포하게 된다.
문제의 핵심은 어떠한 작업이 있을 경우 그 앞의 기능보다 빨리 끝나냐, 아니냐가 중요하다.
문제 풀이
public int[] solution(int[] progresses, int[] speeds) {
ArrayList<Integer> list = new ArrayList<>(); // 배포되는 기능의 갯수를 담을 리스트
Queue<Integer> queue = new LinkedList<>(); // 작업이 걸리는 기간을 담을 큐
for (int i = 0; i < progresses.length; i++) {
if ((100 - progresses[i]) % speeds[i] == 0) {
queue.add((100 - progresses[i]) / speeds[i]); // 작업이 걸린 기간을 담는다.
} else {
queue.add((100 - progresses[i]) / speeds[i] + 1); // 작업이 걸린 기간을 담는다.
}
}
int x = queue.poll();
int count = 1;
while (!queue.isEmpty()) {
if (x >= queue.peek()) { // 첫 번째 작업 기간과 그 다음에 오는 기능의 작업 기간을 비교
count++;
queue.poll();
} else {
list.add(count); // 이때까지 했던 작업들을 리스트에 저장
count = 1; // 배포 횟수 초기화
x = queue.poll(); // 비교 했을때 작업 기간이 더 높은 것으로 교체
}
}
list.add(count);
int[] answer = new int[list.size()];
for (int i = 0; i < answer.length; i++) {
answer[i] = list.get(i);
}
return answer;
}
먼저 배포까지 걸리는 기간을 담을 Queue와 배포되는 기능의 개수를 저장할 ArrayList를 만들었다.
if ((100 - progresses[i]) % speeds[i] == 0) {
queue.add((100 - progresses[i]) / speeds[i]); // 작업이 걸린 기간을 담는다.
} else {
queue.add((100 - progresses[i]) / speeds[i] + 1); // 작업이 걸린 기간을 담는다.
}
매개변수로 받은 작업의 길이만큼 for문을 돌리게 되는데 이 연산이 코드에서 핵심이지 않을까 생각한다.
작업이 걸린 기간들을 Queue에 담게 되면 그다음으로 기간들을 비교하게 된다.
int x = queue.poll();
int count = 1;
while (!queue.isEmpty()) {
if (x >= queue.peek()) { // 첫 번째 작업 기간과 그 다음에 오는 기능의 작업 기간을 비교
count++;
queue.poll();
} else {
list.add(count); // 이때까지 했던 작업들을 리스트에 저장
count = 1; // 배포 횟수 초기화
x = queue.poll(); // 비교 했을때 작업 기간이 더 높은 것으로 교체
}
}
먼저 변수 x에 poll() 메서드를 통해 반환된 값을 저장해 준다.
변수 x로 Queue에 peek() 메서드를 실행한 값과 비교를 하여 x가 클 경우 배포한 횟수를 세는 count 변수를 증가시켜 준다.
x가 작을 경우에는 list에 배포한 횟수를 넣어주고 Queue에서 꺼낸 값을 다시 x에 넣어준다.
Queue<Integer> proQueue = new LinkedList<>();
Queue<Integer> speedQueue = new LinkedList<>();
for (int i = 0; i < progresses.length; i++) {
proQueue.add(progresses[i]);
speedQueue.add(speeds[i]);
}
Queue<Integer> countQueue = new LinkedList<>();
int count = 0;
for (int i = 0; i < progresses.length; i++) {
Integer pro = proQueue.poll();
Integer speed = speedQueue.poll();
while (pro < 100) {
pro += speed;
count++;
}
countQueue.add(count);
count = 0;
}
for (int i = 0; i < countQueue.size(); i++) {
Integer poll = countQueue.poll();
Integer peek = countQueue.peek();
if (poll > peek) {
count++;
}
}
내가 했던 풀이를 살펴보면 Queue를 2개 생성하여 각각 진행률과 작업 속도를 저장했다. 그리고 기간을 저장할 Queue를 또 생성했는데 내가 생각을 너무 복잡하게 한 것 같다.
Queue를 3개나 만들어서 생각이 더 복잡해져 마지막에 작업 기간을 비교하는데 실패하였다. 조금은 간단하게 생각해 볼 필요가 있을 것 같다.
'알고리즘 공부' 카테고리의 다른 글
프로그래머스 - 프로세스 (0) | 2023.12.04 |
---|---|
프로그래머스 - 올바른 괄호 (0) | 2023.12.04 |
프로그래머스 - 같은 숫자는 싫어(Java) (0) | 2023.11.29 |
자바 백준_실버5 - 25206번 (0) | 2023.10.06 |
백준 실버3 2346번(자바) (0) | 2023.09.07 |