April 05, 2023
문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/176962
새로운 과제를 시작할 시각이 되었을 때, 기존에 진행 중이던 과제가 있다면 진행 중이던 과제를 멈추고 새로운 과제를 시작합니다.
hh:mm의 형태로 시간이 주어진다.
멈춰둔 과제가 여러 개일 경우, 가장 최근에 멈춘 과제부터 시작합니다.
import java.util.*;
class Solution {
static class Assignment{
String name;
int start;
int time;
public Assignment(String name, String start, String time){
this.name = name;
String[] tmpStart = start.split(":");
this.start = Integer.parseInt(tmpStart[0]) * 60 + Integer.parseInt(tmpStart[1]);
this.time = Integer.parseInt(time);
}
public Assignment(String name, int start, int time){
this.name = name;
this.start = start;
this.time = time;
}
}
public String[] solution(String[][] plans) {
StringBuilder sb = new StringBuilder("");
// PriorityQueue가 2개, new용, old용
// new용은 시간순으로 처리 -> 시작하는 시간이 되면 무조건 바꿈
PriorityQueue<Assignment> newA = new PriorityQueue<>((a1, a2) -> a1.start - a2.start);
PriorityQueue<Assignment> oldA = new PriorityQueue<>((a1, a2) -> a2.start - a1.start);
for(int i=0; i<plans.length; i++){
newA.add(new Assignment(plans[i][0],plans[i][1],plans[i][2]));
}
Assignment cur = newA.poll();
while(!newA.isEmpty() || !oldA.isEmpty()){
// newA가 empty일 경우
if(newA.isEmpty()){
sb.append(cur.name + " ");
cur = oldA.poll();
continue;
}
Assignment newTop = newA.peek();
// 현재 과제가 끝난 것이 새로운 과제의 시작일 경우
if(newTop.start == cur.start + cur.time){
sb.append(cur.name + " ");
cur = newA.poll();
}
// 현재 과제가 끝나기 전에 새로운 과제의 시작일 경우
else if(newTop.start < cur.start + cur.time){
cur.time = cur.start + cur.time - newTop.start;
cur.start = newTop.start;
oldA.add(cur);
cur = newA.poll();
}
// 현재 과제가 끝나도, 새로운 과제를 시작할 수가 없는 경우 -> Old과제에서 가져오기
else {
sb.append(cur.name + " ");
if(oldA.isEmpty()){
cur = newA.poll();
} else {
// 주요부분 : old과제의 시작 시간은 결국 뽑힌 순간의 시간임
int curTime = cur.start + cur.time;
cur = oldA.poll();
cur.start = curTime;
}
}
}
sb.append(cur.name + " ");
return sb.toString().split(" ");
}
}