写一个函数,输入 n
,求斐波那契(Fibonacci)数列的第 n
项。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
(1)递归:函数自己调用自己
(2)递归的"缺陷":递归到一定程度,会发生"栈溢出"
(3)递归的"时间复杂度":递归总次数*每次递归的次数
(4)递归的"空间复杂度":递归的深度*每次递归空间的大小(注意:"每次递归空间的大小"是个常数,可以基本忽略不计)
递归的"深度":树的高度(递归的过程是一个"二叉树")
假设n对应复杂度T(n),由于if( n <= 1 )执行1次,f(n-1)执行1次,f(n-2)执行1次,然后f(n-1)和f(n-2)执行一次,因此有T(n)=T(n-1)+T(n-2)+4,忽略次要项,得到T(n)=T(n-1)+T(n-2),根据数学知识可得通项式为
下面继续分析下,不通过数学计算,估算其上下极限
上限:令T(n-2)约等于T(n-1),则T(n)=T(n-1)+T(n-2)=2T(n-1)=2*2*T(n-2)=....=2^n*T(0)=2^n,即为O(2^n)
下限:令T(n-1)约等于T(n-2),则T(n)=T(n-1)+T(n-2)=2T(n-2)=2*2*T(n-4)=....=2^(n/2)*T(0)=2^(n/2),即为O(2^(n/2))
所以最后可得到结果,其时间复杂度结果位于O(2^(n/2))和O(2^n)之间
跟所有递归调用一样,每次调用一次,都会进行压栈操作,因此下面分析函数调用时栈空间情况,要求f(n)会执行f(n-1)+f(n-2)需要压栈一次,然后求f(n-1)会执行f(n-2)+f(n-3)需要压栈一次,....,最后直到到f(1),这里以f(5)为例,那么栈情况如下图所示
递归算法的空间复杂度:递归的深度*每次递归所需的辅助空间的个数。
而树的高度即为递归的深度。
则易知空间复杂度为O(n)。
class Solution {
public:int fib(int n) {if(n==0) return 0;if(n==1) return 1;return (fib(n-1)+fib(n-2))%1000000007;}
};
动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划(DP)。
时间复杂度O(n),空间复杂度O(1)
class Solution {public:int fib(int n) {if(n==0) return 0;int func1=0;int func2=1;for(int i=2;i<=n;i++) {int temp=f2;func2=(func1+func2)%1000000007;func1=temp;} return func2;}
};
最近一直在学习Deep Frist Search,也在leetcode上练习了不少题目。从最开始的懵懂,到现在遇到问题基本有了思路。依然清晰的记得今年2月份刚开始刷题的时做subsets的那个吃力劲,脑子就是转不过来到底该如何的递归,甚至试过使用debugger一步步的来看看堆栈到底是如何调用和返回的。经过了几个月的训练后,答题有...
链接: https://www.nowcoder.com/acm/contest/139/B 题意: 求满足以下条件的n*n矩阵A的数量模m:A(i,j) ∈ {0,1,2}, 1≤i,j≤n.A(i,j) = A(j,i), 1≤i,j≤n.A(i,1) + A(i,2) + ... + A(i,n) = 2, 1≤i≤n.A(...
LeetCode 191 Number of 1 Bits 解法一(较为传统都解法):使用将n不断右移,并与1想&得到1的个数;(也有使用除法/2的,明显除法的运行效率要低于位移) 时间复杂度:0(logn) 1 int hammingWeight(uint32_t n){ 2 int count=0; 3...