https://school.programmers.co.kr/learn/courses/30/lessons/176962
과제를 받은 루는 다음과 같은 순서대로 과제를 하려고 계획을 세웠습니다.
구현 문제로 문제 설명에 나와있는 대로 과제를 마치는데 걸리는 시간 'playtime'을 과제 시작 시간에 따라 순서대로 연산하면 된다. 우선 과제 시작 시간이 빠른 순으로 정렬하기 위해 PriorityQueue 구조를 사용해 과제를 저장한다. 다음 과제들을 하나씩 확인해가며 다음 과제 시작 시간 내에 끝내지 못하는 과제인 경우 남은 과제 시간을 새로운 배열에 저장해둔다. 단 진행 중이던 과제를 끝낸 뒤 가장 최근에 멈춘 과제를 효율적으로 찾아 진행해야 하기 때문에 Stack 구조에 남은 과제를 저장한다.
import java.util.*;
class Solution {
public String[] solution(String[][] plans) {
String[] answer = {};
int n = plans.length;
// 1. 과제 시작 시간 순으로 정렬
PriorityQueue<Assignment> pq = new PriorityQueue<>(n, new Comparator<Assignment>() {
@Override
public int compare(Assignment o1, Assignment o2) {
return o1.start - o2.start;
}
});
for (int i = 0; i < n; i++) {
Assignment assignment = new Assignment(plans[i][0], sec(plans[i][1]), Integer.parseInt(plans[i][2]));
pq.add(assignment);
}
Stack<Assignment> stack = new Stack<>();
List<String> result = new ArrayList<>();
// 2. playtime 연산
while (pq.size() >= 2) {
Assignment a = pq.poll();
Assignment b = pq.peek();
int term = b.start - a.start;
if (term < a.playtime) {
stack.add(new Assignment(a.name, a.start, a.playtime - term));
} else {
result.add(a.name);
term -= a.playtime;
// 진행중이던 과제를 끝냈을 때, 잠시 멈춘 과제가 있다면, 멈춰둔 과제를 이어서 진행
while (!stack.isEmpty() && term > 0) {
Assignment next = stack.pop();
if (term >= next.playtime) {
result.add(next.name);
} else {
stack.add(new Assignment(next.name, next.start, next.playtime - term));
}
term -= next.playtime;
}
}
}
result.add(pq.poll().name);
while (!stack.isEmpty()) {
result.add(stack.pop().name);
}
answer = new String[n];
for (int i = 0; i < n; i++) {
answer[i] = result.get(i);
}
return answer;
}
public int sec(String time) {
String[] temp = time.split(":");
return Integer.parseInt(temp[0]) * 60 + Integer.parseInt(temp[1]);
}
class Assignment {
String name;
int start;
int playtime;
public Assignment(String name, int start, int playtime) {
this.name = name;
this.start = start;
this.playtime = playtime;
}
@Override
public String toString() {
return "[name=" + name + ", start=" + start + ", playtime=" + playtime + "]";
}
}
}