|
| 1 | +class MinHeap { |
| 2 | + constructor() { |
| 3 | + this.heap = []; |
| 4 | + } |
| 5 | + |
| 6 | + size() { |
| 7 | + return this.heap.length; |
| 8 | + } |
| 9 | + |
| 10 | + // 값을 힙에 추가 |
| 11 | + push(value) { |
| 12 | + this.heap.push(value); |
| 13 | + let currentIndex = this.heap.length - 1; |
| 14 | + //추가한 값과 부모 노드의 값을 비교하여 오름차순 정렬 수행 |
| 15 | + while ( |
| 16 | + currentIndex > 0 && |
| 17 | + this.heap[currentIndex] < this.heap[Math.floor((currentIndex - 1) / 2)] |
| 18 | + ) { |
| 19 | + const temp = this.heap[currentIndex]; |
| 20 | + this.heap[currentIndex] = this.heap[Math.floor((currentIndex - 1) / 2)]; |
| 21 | + this.heap[Math.floor((currentIndex - 1) / 2)] = temp; |
| 22 | + currentIndex = Math.floor((currentIndex - 1) / 2); |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + // 최솟값을 힙에서 제거하고 반환 |
| 27 | + pop() { |
| 28 | + if (this.heap.length === 0) return null; |
| 29 | + if (this.heap.length === 1) return this.heap.pop(); |
| 30 | + |
| 31 | + const minValue = this.heap[0]; |
| 32 | + this.heap[0] = this.heap.pop(); |
| 33 | + let currentIndex = 0; |
| 34 | + |
| 35 | + while (currentIndex * 2 + 1 < this.heap.length) { |
| 36 | + // 현재 노드의 자식 중에서 더 작은 값을 가진 자식을 찾음 |
| 37 | + let minChildIndex = |
| 38 | + currentIndex * 2 + 2 < this.heap.length && |
| 39 | + this.heap[currentIndex * 2 + 2] < this.heap[currentIndex * 2 + 1] |
| 40 | + ? currentIndex * 2 + 2 |
| 41 | + : currentIndex * 2 + 1; |
| 42 | + |
| 43 | + // 현재 노드의 값이 자식 노드보다 작으면 정렬이 끝난 것이므로 반복 중단 |
| 44 | + if (this.heap[currentIndex] < this.heap[minChildIndex]) { |
| 45 | + break; |
| 46 | + } |
| 47 | + |
| 48 | + // 현재 노드와 더 작은 자식 노드의 값을 교환 |
| 49 | + const temp = this.heap[currentIndex]; |
| 50 | + this.heap[currentIndex] = this.heap[minChildIndex]; |
| 51 | + this.heap[minChildIndex] = temp; |
| 52 | + |
| 53 | + // 다음 순회를 위해 현재 인덱스를 작은 자식의 인덱스로 업데이트 |
| 54 | + currentIndex = minChildIndex; |
| 55 | + } |
| 56 | + |
| 57 | + return minValue; |
| 58 | + } |
| 59 | + //힙의 최솟값을 반환 |
| 60 | + peek() { |
| 61 | + return this.heap[0]; |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +function solution(scoville, K) { |
| 66 | + // 주어진 배열을 최소힙에 넣음 |
| 67 | + const minHeap = new MinHeap(); |
| 68 | + for (const sco of scoville) { |
| 69 | + minHeap.push(sco); |
| 70 | + } |
| 71 | + |
| 72 | + let mixedCount = 0; |
| 73 | + // 힙의 크기가 2 이상이고, 최솟값이 K 미만인 동안 반복 |
| 74 | + while (minHeap.size() >= 2 && minHeap.peek() < K) { |
| 75 | + //가장 작은 두 값을 꺼내서 섞은 후 다시 힙에 넣음 |
| 76 | + const first = minHeap.pop(); |
| 77 | + const second = minHeap.pop(); |
| 78 | + const mixedScov = first + second * 2; |
| 79 | + minHeap.push(mixedScov); |
| 80 | + mixedCount++; |
| 81 | + } |
| 82 | + //남아있는 최솟값이 K 이상이면 섞은 횟수 반환 |
| 83 | + return minHeap.peek() >= K ? mixedCount : -1; |
| 84 | +} |
0 commit comments