프로그래머스에서 제공하는 문제들 중 스택과 큐를 연습하기 위한 문제를 풀었다.
문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/42586
문제 설명
풀이 과정
우선도 순으로 입력한 배열과 각 기능들의 개발 속도를 입력한 배열을 각가 넣어주었을 때 우선도가 가장 높은 기능이 릴리즈될 당시 몇 개의 기능과 함께 릴리즈되는지를 반환하도록 하며 완성도가 100%를 달성하더라도 각 요일이 끝났을 때 일괄적으로 릴리즈를 수행하게 된다.
문제를 효율적으로 풀이하기 위해 큐를 사용하기로 했으며 함께 공개될 기능을 셀 변수와 며칠이 걸릴지 계산할 변수를 각각 선언해주었다.
풀이를 위해 생각한 방법은 큐에 존재하는 요소가 없을 때까지 반복하며 요일을 계속 1씩 추가하는 동안 각 기능의 구현도를 계속 확인하며 한 기능의 구현도가 100%를 넘겼을 때 해당 기능을 공개하도록 했다. 또한 poll()메소드를 호출한 후에 다음 큐를 한 번에 비교하며 함께 완료가 되는 기능을 확인하기 위한 변수까지 활용하도록 하는 것으로 계획을 세웠다.
완료된 기능들의 수는 정확하게 몇개가 되는지 확실하게 알 수 없어 배열의 크기는 가변적이 될 수밖에 없을 것이라 판단했다. 그렇기 때문에 ArrayList를 활용해 가변적인 배열 크기에 대응할 수 있도록 했다.
계산 과정에서는 문제가 없었으나 마지막 부분에서 NullPointerException이 발생했다.
NullPointerException이 발생하는 원인을 찾아보니 모든 결과들이 나온 후에도 while문의 계산결과 > 100의 조건이 계속 진행되며 비어있는 큐를 가리키려 했기 때문이었던 것을 찾아낼 수 있었다.
원인을 해결하기 위해서 while문의 종료 조건에 추가적으로 !isEmpty()메소드를 넣어주게 되었다.
while (!prog.isEmpty()) {
int comp = prog.peek() + days * speeds[index];
if (comp >= 100) {
prog.poll();
index++;
count++;
...
마지막으로 가변 크기를 제어해주기 위한 ArrayList는 문제에서 요구하는 int형 배열로 반환하기에 적합하지 않은 상태를 띄고 있었기 때문에 배열로의 변환이 필요했고, Iterator를 활용해 무사히 배열로 변환을 마칠 수 있게 되었다.
int[] resultArray = new int[list.size()];
Iterator<Integer> it = list.iterator();
for (int i = 0; i < list.size(); i++)
resultArray[i] = it.next();
return resultArray;
최종 코드
package StackQueueProblem;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class FunctionDevelopment {
public static void main(String[] args) {
init();
}
static void init() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
try {
String input = br.readLine();
StringTokenizer st = new StringTokenizer(input);
int[] progresses = new int[st.countTokens()];
int index = 0;
while (st.hasMoreTokens())
progresses[index++] = Integer.parseInt(st.nextToken());
input = br.readLine();
st = new StringTokenizer(input);
index = 0;
int[] speeds = new int[st.countTokens()];
while (st.hasMoreTokens())
speeds[index++] = Integer.parseInt(st.nextToken());
bw.write(Arrays.toString(solution(progresses, speeds)));
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
static int[] solution(int[] progresses, int[] speeds) {
Queue<Integer> prog = new LinkedList<>();
ArrayList<Integer> list = new ArrayList<>();
int count = 0; //동시에 완료된 기능이 몇개인지 세는 변수
int days = 1; //가장 앞선 중요도의 기능이 며칠이나 걸렸는지 세는 변수
int index = 0;
for (int i : progresses)
prog.offer(i);
while (!prog.isEmpty()) {
int comp = prog.peek() + days * speeds[index];
if (comp >= 100) {
prog.poll();
index++;
count++;
while (!prog.isEmpty()) {
if ((prog.peek() + days * speeds[index]) >= 100) {
prog.poll();
index++;
count++;
} else
break;
}
list.add(count);
count = 0;
}
days++;
}
int[] resultArray = new int[list.size()];
Iterator<Integer> it = list.iterator();
for (int i = 0; i < list.size(); i++)
resultArray[i] = it.next();
return resultArray;
}
}
채점 결과