递归
- 自身调用
函数能够自身调用 - 退出条件
必须要有条件退出
递归的模板为
//1.recursion terminator
if(level>=max){
return
}
//2.process logic in current level
process(params...);
//3.drill down
drillDown(params...);
//4.reverse the current level status if needed
reverse(params...);
函数调用过程
函数的调用过程,依赖栈来实现,主要解决的是
- 传递参数给被调函数
- 返回结果给调用函数
由于递归调用是相同的函数,所以其调用栈结构是相同的,其占用的空间也是相同的。cpu有专门的寄存器来存放栈段(Stack Segment)和栈指针(Stack Point),所以相对于堆来讲,仅通过移动指针,便可以分配和回收内存,因此速度比堆要快很多。
习题
1.阶乘
求n的阶乘,当n=1时f(1)=1;当n>1时,f(n)=n*f(n-1);
private static int fact(int n) {
if (1 == n) {
return 1;
} else {
return result = n * fact(n-1);
}
}
函数调用栈一般要保存参数,中间变量,返回结果,返回地址等。
函数调用自身,这便是递归思想,如果要分析出每层的各种信息,对人类来讲,将是件很不自然,很复杂的,也没有必要的事。
2.hanoi塔
由n的规模变为n-1的规模,最后求出n=1的值便开始返回,求出压栈的值。规模从n缩小到n-1,要经三步,第一步是借助c柱将n-1个盘从a移动到b,第二步是将第n个盘从a移到c,第三步是将n-1个盘借助c柱从b移到a。
package com.example.lib2;
public class MyClass {
public static void main(String[] args) {
hanoi(3, 'a', 'b', 'c');
}
private static void hanoi(int n, char a, char b, char c) {
if (1 == n) {
move(1, a, c);
return;
}
hanoi(n - 1, a, c, b);
move(n, a, c);
hanoi(n - 1, b, a, c);
}
private static void move(int n, char a, char c) {
System.out.println("move " + n + " from " + a + " to " + c);
}
}
3.爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public int climbStairs(int n) {
if(n<0){
return 0;
}
if(n==1){
return 1;
}
if(n==2){
return 2;
}
int oneStepBack = 2;
int twoStepBack = 1;
int current = 0;
for(int i=3;i<=n;i++){
current = oneStepBack + twoStepBack;
twoStepBack = oneStepBack;
oneStepBack = current;
}
return current;
}
}