TIL에 매일 알고리즘을 쓰고 있으려니 민망하다💇🏻♀️
하지만 열흘 동안은 완전히 알고리즘에 몰입하는 시간이기 때문에 그저 계속... 계속... 알고리즘을 풀고있다.
1) 어떤 방식으로 알고리즘을 풀 지 신중히 고민하자
어제 나에게 고민을 안겨준 1149 RGB 거리.
어제는 백트래킹으로 시간 초과를 맛보았기 때문에 동적계획법으로 생각을 바꿔보았다.
점화식을 찾을 때는 그냥 쭉 나열해보는 것이 최고였다.
뭘 더 줄이고 머리로 계산한 값만 써놓고 하다보면 다 놓치기 마련이었다.
이렇게 간단하게 그 전까지의 min 값만 잘 저장해두면 되는 것을...🙄🙄🙄
(최솟값을 구해야 하는데 max라고 써둬서 조금 고생했다.)
위 낙서를 코드로 표현하면 다음과 같다.(최솟값)
let [R, G, B] = ary[i].split(" ").map((num) => Number(num));
let valueR = Math.min(R + dp[i - 1][1], R + dp[i - 1][2]);
let valueG = Math.min(G + dp[i - 1][0], G + dp[i - 1][2]);
let valueB = Math.min(B + dp[i - 1][0], B + dp[i - 1][1]);
dp[i] = [valueR, valueG, valueB];
이렇게 간단하게 끝날 문제를 백트래킹에 심취하여 놓쳤다.
문제를 잘 파악해서 가장 효율적인 방법을 찾아내는 것에 집중하자.
2) heap(max heap)
heap은 기본 알고리즘 강의에서도 한 번 다뤘던 적이 있다.
하지만 다른 개념에 비해 확 와닿지 않았는지 금세 잊었고, 결국 11279 최대 힙을 공부하며 풀어야했다.
아래는 백준이 나를 통과시켜준 코드다.
class MaxHeap {
constructor() {
this.storage = [null]; // index = 0 자리를 null로 채워서 쓰지 않게 만들어줌 (편하게);
}
insert(value) {
this.storage.push(value);
let index = this.storage.length - 1;
while (index > 1) {
let parentIndex = Math.floor(index / 2);
if (this.storage[parentIndex] < this.storage[index]) {
let temp = this.storage[index];
this.storage[index] = this.storage[parentIndex];
this.storage[parentIndex] = temp;
index = parentIndex;
} else {
break;
}
}
}
delete() {
let lastIndex = this.storage.length - 1;
let temp = this.storage[lastIndex];
this.storage[lastIndex] = this.storage[1];
this.storage[1] = temp;
let targetIndex = 1;
let maxNum = this.storage.pop();
while (true) {
let leftChildIndex = targetIndex * 2;
let rightChildIndex = targetIndex * 2 + 1;
let maxIndex = targetIndex;
if (
leftChildIndex <= this.storage.length - 1 &&
this.storage[leftChildIndex] > this.storage[maxIndex]
)
maxIndex = leftChildIndex;
if (
rightChildIndex <= this.storage.length - 1 &&
this.storage[rightChildIndex] > this.storage[maxIndex]
)
maxIndex = rightChildIndex;
if (maxIndex === targetIndex) break;
let targetValue = this.storage[maxIndex];
this.storage[maxIndex] = this.storage[targetIndex];
this.storage[targetIndex] = targetValue;
targetIndex = maxIndex;
}
return maxNum;
}
}
let result = "";
const maxHeap = new MaxHeap();
for (let num of ary) {
if (num === 0) {
result += maxHeap.storage.length === 1 ? `0\n` : `${maxHeap.delete()}\n`;
} else {
maxHeap.insert(num);
}
}
console.log(result.trim());
처음에 입력값에 대해 반복문을 사용할 때 매번 console.log 되도록 만들었더니 시간초과를 주었다.
다행히 한 번에 출력되도록 result라는 변수에 모아 마지막에 출력했더니 나를 받아주었다.
이런 과정들을 거쳐 스스로 점점 효율에 대해 많이 고려하는 코드를 작성하게 되는 것이 느껴진다.
또, 코드를 작성하는 방법이 더 여러가지로 떠오르게 되는 것 같다.
이게 바로 알고리즘 효과?!😮
JavaScript와 ECMAScript는 무슨 차이점이 있을까?
오늘은 JavaScript와 ECMAScript를 알아보는 아티클을 읽었다.
어디서 주워들어서 ECMAScript가 스크립트의 표준이라는 것은 알았지만 구체적으로 그 차이를 알게된 것은 처음이었다.
무엇보다 아래에 인용한 부분이 가장 인상깊었다.
국립국어원은 Ecma 인터내셔널, ECMA-262는 표준어고, ECMAScript는 맞춤법과 같은 규칙으로 생각한다면 보다 쉽게 이해할 수 있겠습니다.
이보다 간결하고 와닿는 설명은 없을 것 같다.
추가로 그런 ECMAScript를 준수하는 범용 스크립트 언어가 JavaScript인 것이다:)
아예 모르는 것은 아니었지만 그렇다고 아는 것도 아닌 개념을 확실히 잡고가니 좋은 것 같다.
내일도 1일 1아티클✨✨