pop()
👉 효율성 테스트 통과 못함
제한 사항의 수가 너무 커서 걱정은 했지만 역시나...
힌트를 보니 힙을 꼭 사용해야 하는 문제라고 한다.
JS sort()
메소드가 내가 만드는 것보다 최적화가 잘 되어 있을 거라고 생각했는데 아니었나 보다.
sort()
는 O(nlogn), 최소힙은 O(logn)이란다.
무튼 힙이라는 자료 구조가 JS에서 지원이 되지 않기 때문에 직접 구현을 해야 한다.
부모 인덱스 * 2 + 1
, 오른쪽 자식의 인덱스는 부모 인덱스 * 2 + 2
아래 블로그 글을 참고해서 공부했다.
https://reakwon.tistory.com/42
https://chamdom.blog/heap-using-js/
function solution(scoville, K) {
const heap = new MinHeap();
for (const e of scoville) {
heap.push(e);
}
let result = 0;
while (heap.size() > 1 && heap.peek() < K) {
const min1 = heap.pop();
const min2 = heap.pop();
heap.push(min1 + min2 * 2);
++result;
}
return heap.peek() < K ? -1 : result;
}
class MinHeap {
constructor() {
this.heap = [];
}
size() {
return this.heap.length;
}
peek() {
return this.heap[0];
}
swap(i1, i2) {
[this.heap[i1], this.heap[i2]] = [this.heap[i2], this.heap[i1]];
}
push(v) {
this.heap.push(v);
let i = this.size() - 1;
let parentI = Math.floor((i - 1) / 2);
while (i > 0 && this.heap[i] < this.heap[parentI]) {
this.swap(i, parentI);
i = parentI;
parentI = Math.floor((i - 1) / 2);
}
}
pop() {
if (this.size() === 0) return null;
if (this.size() === 1) return this.heap.pop();
const minV = this.heap[0];
this.heap[0] = this.heap.pop();
let i = 0;
while (i < this.size()) {
const leftI = i * 2 + 1;
const rightI = i * 2 + 2;
let small = leftI;
if (rightI < this.size() && this.heap[leftI] > this.heap[rightI]) {
small = rightI;
}
if (this.heap[small] < this.heap[i]) {
this.swap(small, i);
}
i = small;
}
return minV;
}
}