题目描述
简单斐波那契数列铺垫
写法一 简单递归
注意递归一定要有终点,如此终点是n为0或1。
时间复杂度接近2^n,很差不可用
空间复杂度O(N)
int fib(int n) {
if (n == 0)
{
return 0;
}
if (n == 1)
{
return 1;
}
return fib(n - 1) + fib(n - 2);
}
写法二 动态规划
动态规划是分治思想的延伸,通俗一点来说就是大事化小,小事化无的艺术。
在将大问题化解为小问题的分治过程中,保存对这些小问题已经处理好的结果,并供后面处理更大规模的问题时直接使用这些结果。
时间复杂度O(n)
空间复杂度O(n)
int fib(int n)
{
int *fibs = (int *)malloc(sizeof(int) * n);
//状态初始化
fibs[0] = 0;
fibs[1] = 1;
if(n==0||n==1)
{
return fibs[n];
}
//状态间的转移方程
for (int i = 2; i <= n; ++i)
{
fibs[i] = fibs[i - 1] + fibs[i - 2];
}
return fibs[n];
}
写法三 优化动规
实际上只为了求得第n项的值,只需要三个变量就可以完成了。
时间复杂度O(n)
空间复杂度O(1)
int fib(int n)
{
if(n==0||n==1)
{
return n;
}
int fn = 0;
int fn1 = 0;
int fn2 = 1;
for (int i = 2; i <= n; ++i)
{
//状态转移方程
fn = fn1 + fn2;
fn1 = fn2;
fn2 = fn;
}
return fn;
}
LeetCode 题解
这题的难点在于极大的第n项,并且输出值要对1e9+7取余。
注意理解为什么当fn大于1e9+7时,对1e9+7取余,(类似映射的思想)。
int fib(int n) {
if(n==0||n==1)
{
return n;
}
int fn = 0;
int fn1 = 0;
int fn2 = 1;
for (int i = 2; i <= n; ++i)
{
//状态转移方程
fn = fn1 + fn2;
if(fn>1e9+7)
{
fn %=1000000007;
}
fn1 = fn2;
fn2 = fn;
}
return fn;
}
斐波那契数列的求解是动态规划思想的简单体现,借此可以初步了解动态规划思想。
码字不容易,欢迎关注,点赞,收藏,评论,转发。