递归
刷leetcode做算法题经常会遇到需要使用递归来解答的题目,总是在能做出来的边缘,差那么点火候。算法这块实在是太菜了,需要好好地补补课。故学习了一些大神总结的递归学习法,这里做一些笔记,希望之后遇到递归题目的时候能顺利的解答出来。
递归的三大要素
第一:明确你这个函数想要干什么
例如:
1 | // 算 n 的阶乘(假设n不为0) |
这个函数的功能就是计算n的阶乘
第二:寻找递归结束条件
所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,不然的话,会一直调用自己,进入无底洞。也就是说,我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。
例如:
1 | int f(int n){ |
第三:找出函数的等价关系式
寻找原函数的一个等价关系式,例如:f(n) = n * f(n-1)
1 | //用递归的方法反转链表 |
递归的优化方法
考虑是否重复计算
根据这3个要素,即可以写出递归函数,但递归如果不进行优化,则有很多子问题被重复计算。
一般我们可以把我们计算的结果保存起来,用HashMap或者用数组,通过下表获取n对应的值。典型的用空间换时间的做法。
考虑是否可以自底向上
递归我们一般都是从上往下进行递归的,比如n = 10000时,我们要从10000一直递归到1才返回结果,如果n太大的时候,栈的空间可能不够用。
上述递归方案可以修改成如下代码:
1 | public int f(int n) { |