算法思维--递归

今天学习了一下算法思维–递归思想;递归是衡量一个程序员初中级的分水岭,主要是代码可读性强,可以使得代码更加简洁。

初识递归

举个例子:在抗战时期,某个队伍中在夜里行军,由于天色昏暗,无法确认某某士兵所在的位置是多少号(这里指的是士兵距离最前一位士兵的位置),这个的时候可以模拟递归的思维,只要改士兵找到前面的士兵,询问相同的问题,以此类推,一直往前,直到找到第一个士兵的时候,之后又从第一个士兵返回,也已相同的形式像报数一样的告诉他所在的位置。
分析:整个过程如其名字一样一个递的过程和一个归的过程。可以简单的使用数学思想表达:f(n)=f(n-1)+1;如此以来,就确定了一个未知的士兵的位置。

 public static  int  funcdg(int n){
        if (n<2){
            return 1;
        }
        return funcdg(n-1)+1;
    }

代码大致如此
总结一下以上的思想:可以得出一些什么场景下使用递归的思路。
1.一个大问题可以拆分成无数的相同的小问题,如上,我在哪个位置?这个大问题可以分给前面的每个士兵相同的小问题。
2.最终总有一个已知解,第一个士兵一定知道自己在哪个位置,因为他前面没有人

基于以上的思路在学习下经典的递归算法使用场景–》》斐波拉契序列,也就是前两个数字之和得到第三个数字,数学表达F(n)=F(n-1)+F(n-2);
 public static int fbl(int n){
        if (n<=2){
            return 1;
        }
        return  fbl(n-1)+fbl(n-2);
    }

三行代码就解决了这个问题。是不是很简洁?同时也符合以上所说的思想,即要求得第几个数字的斐波拉契数字是多少,这个问题可以一直拆分成相同的问题,最终找到,F(1)=1,F(2)=1;这个问题就迎刃而解。
基于上述问题,其实也可以看到时间复杂度和空间复杂度在2^n
在这里插入图片描述

如何优化?

使用缓存数组解决问题:

private static  int[] data;//缓存数组
//使用缓存作用降低空间复杂度O(n)
    public static int fbl2(int n){
        if (n<=2){
            return 1;
        }
        if (data!=null&&data[n]!=0){
            return data[n];
        }
        int res=fbl2(n-1)+fbl2(n-2);
        data[n]=res;
        return res;
    }

private static int[] data;声明一个静态的缓存数组即可。这样的话就可以减少一些相同的裂变,例如F(3)=F(1)+F(2)这种裂变,从而降低时间复杂度和空间复杂度
使得为O(n)

斐波拉契可以转化为非斐波拉契
 /**
     *使用非菲薄啦求解===》递归算法一定可以转化为非递归算法
     */
    public static int nofbl(int n){
        if (n<=2){
            return 1;
        }
        int f1=1;
        int f2=1;
        int f3=0;
        for(int i=3;i<=n;i++){
            f3=f1+f2;
            f1=f2;
            f2=f3;
        }
        return f3;
    }

这个可以和之前的递归做比较可以看出递归代码的简洁和易读性

尾递归

尾递归算法是一个比较高级的递归思想,一般的话,很容易出错,所以用得好的额一般是大神。我这里也是简单介绍。大致的思想是,只有递的过程没有归的过程。同时也要return 中只有方法名没有其他的参数。
先看一个阶乘的算法:

 /*
    * 求一个阶乘!
    *
    * */
    public static int qjc(int n){
        System.out.println("求出的值为:"+n);
        if (n<2){
            return 1;
        }
        return n*qjc(n-1);
    }

改成尾递归:

 public static int tailarch(int n,int res){

        if (n<2){
            return n*res;
        }
        return tailarch(n-1,n*res);
    }

可以把以上的斐波拉契改成尾递归

 public static int tailarch2(int pre,int res,int n){
        if (n<=2){
            return 1;
        }
        return tailarch2(res,pre+res,n-1);
    }

这就是今天以上所学!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值