1. 제출 코드 (2시간 19분 57초 / 구현)
import java.util.*;
class Solution {
static class Node {
String name;
String start;
int playtime;
public Node(String name, String start, int playtime) {
this.name = name;
this.start = start;
this.playtime = playtime;
}
}
public String[] solution(String[][] plans) {
String[] answer = new String[plans.length];
int index = 0;
// 과제 실행 순서
ArrayDeque<Node> st = new ArrayDeque<>();
// 과제 시간 순서대로 정렬
Arrays.sort(plans, (o1, o2) -> {
String[] t1 = o1[1].split(":");
String[] t2 = o2[1].split(":");
int time_diff = Integer.parseInt(t1[0]) - Integer.parseInt(t2[0]);
if(time_diff != 0) {
return time_diff;
} else {
return Integer.parseInt(t1[1]) - Integer.parseInt(t2[1]);
}
});
for(int i = 0; i < plans.length; i++) {
Node start = new Node(plans[i][0], plans[i][1], Integer.parseInt(plans[i][2]));
// 과제가 없을 경우
if(st.isEmpty()) {
st.add(start);
} else {
Node t = st.peekLast();
int time_diff = calc_time(t, start);
// 과제를 새로 시작하기 전까지 끝나는 과제 처리
while(time_diff > 0) {
// 만약, 진행 중인 과제가 새로 시작하는 과제 시간 이상으로 해야한다면 playtime 업데이트
if(time_diff < t.playtime) {
t.playtime = t.playtime - time_diff;
break;
} else {
// 과제를 새로 시작하기 전에 처리될 수 있는 진행 과제 삭제
Node temp = st.pollLast();
time_diff -= temp.playtime;
answer[index++] = temp.name;
if(st.isEmpty()) break;
// 진행 중인 과제를 중간에 처리했으니 새로운 과제 부여
t = st.peekLast();
}
}
st.add(start);
}
}
while(!st.isEmpty()) {
answer[index++] = st.pollLast().name;
}
return answer;
}
// 새로 시작하는 과제와 잠시 멈춰둔 과제 사이의 시간 측정(분 단위)
private int calc_time(Node t1, Node t2) {
String[] ts1 = t1.start.split(":");
String[] ts2 = t2.start.split(":");
int m1 = Integer.parseInt(ts1[1]);
int m2 = Integer.parseInt(ts2[1]);
int time_diff = 0;
int diff_hour = Integer.parseInt(ts2[0]) - Integer.parseInt(ts1[0]);
if(diff_hour > 0) {
if(m2 < m1) {
time_diff += (diff_hour - 1) * 60;
} else {
time_diff += diff_hour * 60;
}
}
if(m2 >= m1) {
time_diff += m2 - m1;
} else {
time_diff += (60 - m1) + m2;
}
return time_diff;
}
}
2. 구현 로직
- 과제를 시간 순서대로 정렬
- for문을 이용해서 과제 하나씩 탐색
- stack이 비어있을 경우, 과제 하나 삽입
- stack 비어있지 않을 경우, 새로 시작하는 과제와 stack에 있는 과제와의 시간 차를 계산
- 시간 차 > 0 일때까지 반복 작업
- 시간 차보다 stack에 있는 playtime이 더 클 경우, stack에 있는 playtime = playtime - 시간차
- 시간 차보다 stack에 있는 playtime이 작거나 같을 경우, stack의 맨 위 과제를 제거하고 playtime만큼을 제거하고도 새로운 과제를 시작하기 전까지 시간차가 남아있을 수도 있으므로 비교 값을 stack의 맨 위 과제로 갱신
- stack의 맨위부터 하나씩 과제를 처리
3. 유의할 점
- 5.2 부분에서 stack 맨 위 과제를 갱신할 때, stack이 비어있는지 검사를 하지 않아서 런타임 에러가 계속 발생했다. stack empty 체크하는 것을 주의해야겠다.