3가지 조건
마지막 3번째는 피보나치 수열을 생각하면 된다. 많은 계산을 줄일 수 있다.
피보나치 수열은 층 수가 하나 늘어날 때마다 2가 곱해지면서 총 n개의 층이 있다. 따라서 O(2^n) 의 time complexity를 가진다.
Fn = F(n-1) + F(-2)
int fibonacci(int n)
{
if (n == 0) return 0;
else if (n == 1) return 1;
else
{
int fib = fibonacci(n - 1) + fibonacci(n - 2);
return fib;
}
}
이는 2^n의 time complexity를 가지게 된다.
거르는거 없이 중복 되는 것도 계속 계산해 나가는 것이다.
이를 recursive한 DP로 풀게 되면 중복을 피할 수 있는데 문제가 있다.
stack call에는 한계가 있는데, top down 방식의 프로그래밍으로는 한계가 있어서 recursion의 depth가 stack overflow 해 버린다.
bottom up 방식으로 가장 작은 problem부터 가장 큰 problem 까지 올라가면서 해결하면 좀 더 좋은 방식이 될 것이다.
vector<int> fiboarr{ 0, 1 };
int fibonacci(int n)
{
for (int i = 0; i < 2; ++i)
{
if (fiboarr[i] == n)
return fiboarr[i];
}
for (int i = 2; i <= n; ++i)
{
fiboarr.push_back(fiboarr[i - 1] + fiboarr[i - 2]);
}
return fiboarr[n];
}
O(n) 의 time complexity를 가지고, O(n)의 space complexity를 가진다.
이를 optimization의 관점으로 보면 space를 O(1)으로 줄이는게 가능하다.
int fibonacci(int n)
{
if (n == 0) return 0;
else if (n == 1) return 1;
vector<int> vArray{ 0, 1 };
for (int i = 0; i <= n - 2; ++i)
{
vArray.push_back(vArray[0] + vArray[1]);
vArray[0] = vArray[1];
vArray[1] = vArray[2];
vArray.pop_back();
}
return vArray[1];
}