과제를 받은 루는 다음과 같은 순서대로 과제를 하려고 계획을 세웠습니다.
과제 계획을 담은 이차원 문자열 배열 plans가 매개변수로 주어질 때, 과제를 끝낸 순서대로 이름을 배열에 담아 return 하는 solution 함수를 완성해주세요.
3 ≤ plans의 길이 ≤ 1,000
진행중이던 과제가 끝나는 시각과 새로운 과제를 시작해야하는 시각이 같은 경우 진행중이던 과제는 끝난 것으로 판단합니다.
plans : [["korean", "11:40", "30"], ["english", "12:10", "20"], ["math", "12:30", "40"]]
["korean", "english", "math"]
function solution(plans) {
var answer = [];
class MinHeap {
constructor() {
this.heap = [null];
}
enqueue(value) {
this.heap.push(value);
let current = this.heap.length - 1;
let parent = Math.floor(current / 2);
while (parent > 0 && this.heap[current][1] < this.heap[parent][1]) {
[this.heap[current], this.heap[parent]] = [this.heap[parent], this.heap[current]];
current = parent;
parent = Math.floor(current / 2);
}
}
dequeue() {
if (this.heap.length === 1) return null;
if (this.heap.length === 2) return this.heap.pop();
let result = this.heap[1];
this.heap[1] = this.heap.pop();
let current = 1;
while (true) {
let smallest = current;
let left = 2 * current;
let right = left + 1;
if (left < this.heap.length && this.heap[left][1] < this.heap[smallest][1]) {
smallest = left;
}
if (right < this.heap.length && this.heap[right][1] < this.heap[smallest][1]) {
smallest = right;
}
if (smallest === current) break;
[this.heap[current], this.heap[smallest]] = [this.heap[smallest], this.heap[current]];
current = smallest;
}
return result;
}
peek() {
if (this.heap.length === 1) return null;
return this.heap[1];
}
getSize() {
return this.heap.length - 1;
}
}
let timePlan = new MinHeap();
for (let i = 0; i < plans.length; i++) {
let [name, start, playtime] = plans[i];
start = start.split(":").map(Number);
start = start[0] * 60 + start[1];
timePlan.enqueue([name, start, Number(playtime)]);
}
let currentTime = timePlan.peek()[1];
let current = null;
let ready = [];
while (timePlan.getSize()) {
if (!current && ready.length > 0) {
current = ready.pop();
}
if (!current && currentTime < timePlan.peek()[1]) {
currentTime = timePlan.peek()[1];
}
if (current) {
current[2]--;
if (current[2] === 0) {
answer.push(current[0]);
current = null;
}
}
while (timePlan.getSize() && currentTime === timePlan.peek()[1]) {
if (current && current[2] > 0) {
ready.push(current);
}
current = timePlan.dequeue();
}
currentTime++;
}
if (current) answer.push(current[0]);
while (ready.length > 0) {
answer.push(ready.pop()[0]);
}
return answer;
}
ready에 들어간 문제를 큐로 받아들여서 왜... 테케가 저렇게 될까 고민을 한참했는데 문제를 또 대충 읽었다...ㅜ 그것만 아니면 생각보다 쉽게 풀린 문제 보통 그리디로 푼다고 하는데 최근 우선순위 큐를 많이 접해서 그런가 우선순위가 바로 생각났다.