剑指offer java版 test7—递归 尾递归和动态规划

剑指offer java版 test7—递归 尾递归和动态规划

(原以为是简简单单的一题,看了评论区大佬的解答,才知道别有洞天,还有很多值得我学习的知识。)
(这一题我以为就是一个递归,原来还牵扯到更好的解决方法:尾递归,动态规划,循环)

题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 n<=39

先把整体的知识点整理一下:

  1. 递归:在函数体内调用自身
    递归的特点:理论上来说,所有的递归都可以用循环体来做。但是递归的定义更为简单,逻辑清晰,看着更易懂。同时使用递归函数的时候,要注意防止栈溢出。在计算机中,函数的调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回时,栈就会减一层栈帧,由于栈的大小并不是无限的,所有递归调用的次数过多时,会导致栈的溢出。

  2. 尾递归:进入下一个函数时,不再需要上一个函数的环境了,得出结果以后可以直接返回,不需要一层一层的向上返回。
    **
    (这个博客解释的很明白,第一个例子,解释的代码运行的步骤,很容易看明白递归和尾递归的区别:https://blog.csdn.net/weixin_40539125/article/details/88043983
    但是例子结果不对,正确代码结果见这边:https://www.cnblogs.com/gwf93/p/10295116.html)**

    能解决栈溢出的原因在于:结合这个博客的例子,我们就很容易理解为什么尾递归不会出现栈溢出的问题,因为尾递归调用进入下一个函数时,不需要像递归一样保留当前的结果,所以可以通过覆盖当前的栈帧,而不是重新添加一个(只保留一个函数堆栈即可,前面的删去)这样就不会造成栈溢出了。
    (即:通常递归都是在栈上根据调用顺序依次申请空间进行运算,然后层层回调,这是基于上一层运算依赖于下一层的运算结果(或者说上一层的运算还没用做完,需要下一层返回的结果) 而尾递归的情况是下层计算结果对上层“无用”(上一层运算已经做完,不依赖后续的递归),为了效率,直接将下一层需要的空间覆盖在上一层上)

    特点:可以解决递归栈溢出的问题,事实上,尾递归和循环的效果一样,所以可以把循环看成一种特殊的尾递归函数。

本题的解答:
递归代码:

package cn.test7;
/*
斐波那契数列
1 1 2 3 5 8 13 21 34

 */
public class QueneTest {
    public static void main(String[] args){
        Solution n=new Solution();
       System.out.println( n.Fibonacci(6));
    }
}

class Solution{
    public int Fibonacci(int n){
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        return Fibonacci(n-1)+Fibonacci(n-2);

    }
}

尾递归代码(代码思路,先算0+1 再算1+1 再算1+2,…,按照这个思路来写代码):

package cn.test7;
/*
用非递归做
 */
public class QueneTest2 {
    public static void main(String[] args){
        Solution1 n=new Solution1();
        System.out.println( n.Fibonacci(6));
    }
}

class Solution1{
    public int Fibonacci(int n){
        return Fibonacci1(n,0,1);
    }

    public int Fibonacci1(int n,int num1,int result){
        if(n==0) return 0;
        if(n==1) return result;
        return Fibonacci1(n-1,result,num1+result);
    }
}

动态规划待下次介绍。循环就不介绍了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值