피보나치 수열을 예를 들어보자면, 점화식은 F(n) = F(n-1) + F(n-2)가 된다.
이는 간단하게 재귀함수만으로 구현할 수 있지만, 비교적 그렇게 어마어마하게 크지 않은 수인 50만 생각해보더라도 50을 구하기 위해서 불필요한 재귀가 일어나게 되어 엄청나게 많은 연산이 요구된다.
위의 그림에서도 알 수 있듯이 5를 구하기 위해서 다른 것들이 중복해서 계속 재귀적으로 호출되고 있다.
따라서 다이나믹 프로그래밍을 사용하여 이미 구한 값은 메모이제이션으로 저장을 해놓아서 불필요한 연산 횟수를 줄이면 성능이 매우 좋아진다. 그렇게 되면 시간복잡도가 O(n)으로 해결이 가능해진다.
function fib(n){ //재귀형 O(2^n)
if(n === 1) return 1;
if(n === 2) return 1;
return fib(n-1) + fib(n-2);
}
function fib(n,memo=[]){
if(memo[n] !== undefined) return memo[n]; //있으면 가져다쓰겠다
if(n<=2) return 1;
var res = fib(n-1,memo) + fib(n-2,memo);
memo[n] = res;
return res;
}
function fib(n){
if(n<=2) return 1;
let fibNums = [0,1,1];
for(let i=3; i<=n; i++){
fibNums[i] = fib(i-1) + fib(i-2);
}
return fibNums[n];
}