经典递归问题集锦

总体来说递归基本可表述成以下类似的结构:

递归调用(参数) {

if (基本情形) {

// ...

// 完成,收工

} else { // 递归情形

// ...

递归调用( 新参数 );

}

}

因此,写递归程序一是明确基本情形,二是找出递归情形。

eg1:求阶乘

也就是输入一个数,然后求出他的阶乘,例如输入5,则求5!=120

分析:

画出示意图如下:
这里写图片描述

可以看出基本情形就是1!=1,特殊情形就等于f(n-1),所以程序如下

private static int getIndex(int n) {
        if (n==1) {
            return 1;//基本情况
        }else{
            return n * getIndex(n-1);//特殊情况
        }
    }

eg2:斐波那契数列

输入一个数表示斐波那契数列的第几项,然后找出这一项的值

分析:
这里写图片描述

可以看出基本情景就是f(2)=1,f(1)=1,特殊情景就是f(n-1)+f(n-2)
所以程序如下

private static int getIndex(int n) {
        if (n==1||n==2) {
            return 1;//基本情况
        }else{
            return getIndex(n-1)+getIndex(n-2);//特殊情况
        }
    }

eg3:汉诺塔问题

大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

分析三个柱子分别是ABC,现在要从A移动到C
当只有一个盘子时,只需要A->C
当有两个盘子的时候,先A->B,再A->C,再B->C
当有三个盘子的时候,先把前两个借助C移动到B,然后再把第三个移动到C,剩下两个再如此进行
当有N个盘子的时候,先把N-1个盘子借助C移动到B,再把第N个移动到C,剩下N-1个盘子,再借助C移动到AN-2个,再把第N-1个盘子移动到C,如此循环
这里写图片描述

对于图片又要解释的就是,移动分两步,一步是移动到目标,另一步则是借助一个柱子,移动N-1个到空闲柱子,那基本情况就是当盘子为1的时候,直接移动到目标,代码如下

private static void move(int n,char from,char to,int i){
            System.out.println("移动第"+n+"个盘子从"+from+"-->"+to+"--"+i);
    }

private static void hanoi(int n,char from,char depand_on,char to){
        if (n==1) {
            move(n, from, to,1);//如果只剩最后一个盘子就将盘子移动到指定位置
        }else {
            hanoi(n-1, from, to, depand_on);
            move(n, from, to,0);
            hanoi(n-1, depand_on, from, to);
        }

    }

这里写图片描述

看输入,每动其他盘子,后面必要动第一个盘子,也就是执行N==1这个情况

文章导航