查找斐波纳契数列中第 N 个数。
所谓的斐波纳契数列是指:
- 前2个数是 0 和 1 。
- 第 i 个数是第 i-1 个数和第i-2 个数的和。
斐波纳契数列的前10个数字是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...
样例
给定 1
,返回 0
给定 2
,返回 1
给定 10
,返回 34
虽然这道题是一道入门级的题目,可是在第一遍做的时候并没有多想,直接使用的递归,然后数据通过95%,显示的到47的时候就溢出了。经过学习前辈的经验,该题的收获如下:
方法1:使用递归解,时间复杂度是n的指数级别
方法2:开辟一个长度为(n+1)的数组,时间复杂度为O(n),空间复杂度为O(n)
我们计算f(0)、f(1)、f(2)、f(3)。。直到f(n),将这些计算出来的值保存在一个数组arry[n+1]上,这样计算斐波那契数列就相当于是一个填表的过程。时间复杂度大大降低
1 int Fibonacci(int n) 2 { 3 if(n<=0) 4 return 0; 5 else if(n==1) 6 return 1; 7 else 8 { 9 //动态创建一个长度为(n+1)的数组 10 int *arry=new int[n+1]; 11 arry[0]=0; 12 arry[1]=1; 13 for(int i=2;i<=n;i++) 14 { 15 arry[i]=arry[i-1]+arry[i-2]; 16 } 17 int result=arry[n]; 18 delete [] arry; 19 return result; 20 } 21 }
c++提供delete []表达式释放指针所指向的数组空间。delete [] arry;该语句回收了arry所指向的数组,把相应的内存返回给自由存储区。在关键字delete和指针arry之间的方括号[]是必不可少的:它告诉编译器该指针指向的是自由存储区中的数组,而非单个对象。delete arry只释放了arry指针所指向的内存地址,理论上来说会少释放了内存空间,从而产生内存泄露。
方法3:只保留两个空间变量,空间复杂度为O(1),时间复杂度为O(n)
1 class Solution { 2 /** 3 * @param n: an integer 4 * @return an integer f(n) 5 */ 6 public int fibonacci(int n) { 7 // write your code here 8 if( n <= 1 ) { 9 return 0 ; 10 } else if (n ==2 ){ 11 return 1 ; 12 } 13 else { 14 int pre = 0 ; 15 int post = 1 ; 16 int fn = 0 ; 17 for(int i=2 ;i<n;i++){ 18 fn = pre + post; 19 pre = post; 20 post = fn; 21 } 22 return fn; 23 } 24 } 25 }
相关题目: 爬楼梯
假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?
样例
比如n=3,1+1+1=1+2=2+1=3,共有3中不同的方法
返回 3
public class Solution { /** * @param n: An integer * @return: An integer */ public int climbStairs(int n) { // write your code here if (n ==0 ) return 1;//这道题的本质其实和上道题一样,不过我在做这题的时候忽略了n=0的情况,多多练习,多多加油吧 if (n ==1 ) return 1; if (n ==2 ){ return 2; } else{ int pre = 1; int post = 2; int fn=0; for(int i = 3; i<=n; i++){ fn = pre+post; pre = post; post = fn; } return fn; } } }