递归理解

首先,要理解递归,不要去在脑子里想这个递归过程,因为很容易绕进去,人的大脑压入不了几个栈,要相信递归可以完成某个问题,否则就会陷入细节中,无法跳出来。

递归本质是自己调用自己,把大问题化成相同小问题的解决问题的思路,是一种编程技巧。

理解递归

举个例子,比如去电影院,你女朋友问你这是第几排,你问前一排人,前一排人也不知道,就再问前一个人,知道第一排,然后再一排一排的传回来,去问的过程是递,回来的过程是归,总结成代码就是

public int f(int n){

        if (n==1){
            return 1;
        }
        return f(n-1)+1;
}

递归二要素

  • 相同子问题。大问题可以分解为规模不同,思路相同的小问题
  • 存在终止条件

递归求解步骤

  • 根据问题分解,寻找子问题,找规律写出递归公式
  • 找到其中的终止条件

举个例子:
假如有N个台阶,每次可以走一个或者两个台阶,请问有多少种走法?
第一步走的时候会有两种走法,走一步或者走两步,那么N个台阶的走法就等于N-1个台阶的走法+N-2个台阶的走法。所以推导出公式

f(n)=f(n-1)+f(n-2)

下一步我们来找终止条件,当只有一个台阶的时候,那就只有一种走法了,即f(1)=1;当有两个台阶的时候,可以一次走一步或者一次走两步,这样f(2)=2;当有3个台阶的时候,可以分为f(2)+f(1),所以终止条件是f(1)=1,f(2)=2;
最终代码:

public int f(int n) {
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }

        return f(n - 1) + f(n - 2);
}

堆栈问题

函数调用会用栈来保存信息,每调用一个函数,就会将临时变量封装成栈帧压入栈中,函数执行结束才出栈返回,如果递归规模较大,会超出系统栈或者虚拟机栈空间。

提前在代码层面做好递归最大深度的控制

递归优化

递归过程中,有可能会出现重复子问题,例如菲波那切数列
在这里插入图片描述
我们可以通过利用hashMap将计算过的结果存储起来,这样就可以达到优化重复计算的问题。

非递归转换

本质上所有的递归代码都可以改为迭代循环的非递归写法。

递归代码虽然高效,但是需要注意堆栈溢出、重复计算、函数调用、空间复杂度高等。

递归算法应用

路径总和 III
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值