面试题:f(n) = f(n-1) + f(n-2) 求 f(100)
问题:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
看到这个就想起了上学的时光,那个苦啊.
废话不多说,当时看到这个问题我就想到了递归,然后匆匆写了代码如下:
1 public static int fn(int n) { 2 3 if(n == 1) { 4 return 1; 5 } else if(n == 2) { 6 return 2; 7 } else { 8 return fn(n - 1) + fn(n - 2); 9 } 10 11 }
但是考虑不够全面,1.没有考虑会不会减到0或者负数 2. 如果n的数值小还行,,n为100的情况,递归太深,这样会极大的消耗你的内存,
然后问度娘:https://baike.baidu.com/item/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97
像高中和大学那会,,一般这种都是有通项公式的,不过推导过程太过烧脑,请参照度娘提供的方法;
然后根据通项公式整理代码如下:
1 public static double fnn(int n) { 2 double a = Math.sqrt(5); 3 double b = 1 / a; 4 double c = Math.pow((1 + a) / 2, n); 5 double d = Math.pow((1 - a) / 2, n); 6 double e = b * (c - d); 7 return e; 8 } 9 10 public static void main(String[] args) { 11 System.out.println(fnn(10)); 12 }
我想面试如果考这种题目,一般是考察递归,内存溢出,算法,,,这个仅代表个人愚见,代码也有不足支出,仅供大家呵呵,欢迎大家提意见.
割=================================================================================================
最进有了新的想法:尾递归
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
百度百科:https://baike.baidu.com/item/%E5%B0%BE%E9%80%92%E5%BD%92/554682
百科解释的很清楚,,那么这道题就可以这么做了:
1 // 0 2 // 102334155 3 private static Integer fun1(int n, int ret1, int ret2) { 4 if (n == 0) { 5 return ret1; 6 } 7 return fun1(n - 1, ret2, ret1 + ret2); 8 9 } 10 11 // 1361 12 // 102334155 13 private static Integer fun(int n) { 14 if (n == 0) { 15 return 0; 16 } else if (n == 1 || n == 2) { 17 return 1; 18 } else { 19 return fun(n - 1) + fun(n - 2); 20 } 21 } 22 23 public static void main(String[] args) { 24 long t0 = System.currentTimeMillis(); 25 Integer fun = fun1(40, 0, 1); 26 long t1 = System.currentTimeMillis(); 27 System.out.println(t1 - t0); 28 System.out.println(fun); 29 }
里面有两种我本地的运行时间和结果,,,大大的优化啊,