Java----递归练习题(3.13)

递归求 N 的阶乘

    public static int prime(int n) {
        if(n==1) {
            return 1;
        }
        return n*prime(n-1);
    }

按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)

  public static void oneBit(int n) {
        if(n > 9) {
            oneBit(n / 10);
        }
        System.out.println(n % 10 + " ");
    }

求 1 + 2 + 3 + … + 10

public static int add(int n) {
    if (n == 1) {
        return 1;
    }
    return n + add(n - 1);
}

写一个递归方法,输入一个非负整数,返回组成它的数字之和.

public static int oneAdd(int n) {
    if (n < 10) {
        return n;
    }
    return n % 10 + oneAdd(n / 10);
}

递归求斐波那契数列的第 N 项

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

循环求斐波那契数列的第 N 项

   public static int fib(int n) {
        int last2 = 1;
        int last1 = 1;
        int cur = 1;
        for (int i = 3; i <= n; i++) {
            cur = last1 + last2;
            last2 = last1;
            last1 = cur;
        }
        return cur;
    }

汉诺塔问题

汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。 并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。 问应该如何操作?

设3根柱子分别为A,B,C.
1个圆盘:1 次 A>C
2个圆盘:3 次 A>B,A>C,>B>C
3个圆盘:7 次 A>C,A>B,C>B,A>C,B>A,B>C,A>C
4个圆盘:15次 A->B,A->C,B->C,A->B,C->A,C->B,A->B,A->C ,B->C,B->A,C->A,B->C,A->B,A->C,B->C
n个圆盘:2^n-1次

实现这个算法可以简单分为三个步骤:
(1) 把n-1个盘子由A 移到 B;
(2) 把第n个盘子由 A移到 C;
(3) 把n-1个盘子由B 移到 C;

(1)中间的一步是把最大的一个盘子由A移到C上去;
(2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
(3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;

import java.util.Scanner;
public class TestDemo {
    static int m =0;//存放移动次数
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        char p1 = 'A';
        char p2 = 'B';
        char p3 = 'C';
        HanoiTower(n,p1,p2,p3);
        System.out.println();
        System.out.println("需要移动" + m + "次");
    }  
	public static void HanoiTower(int n,char p1,char p2,char p3) {
        if (n == 1) {//圆盘只有一个时,只需将其从A塔移到C塔
            move(p1,p3);//将编b号为1的圆盘从A移到C
            return ;
        }
        //递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔
        HanoiTower(n-1,p1,p3,p2);
        
        //把A塔上编号为n的圆盘移到C上
        move(p1,p3);
        
		//递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔
        HanoiTower(n-1,p2,p1,p3);
    }
    
    public static void move(char p1,char p3) {
    	++m;
        System.out.print(p1 + "->" + p3 +"  ");
    }
}
**对递归的理解的要点主要在于放弃!放弃你对于理解和跟踪递归全程的企图,只理解递归两层之间的交接,以及递归终结的条件。想象你来到某个热带丛林,意外发现了十层之高的汉诺塔。正当你苦苦思索如何搬动它时,林中出来一个土著,毛遂自荐要帮你搬塔。他名叫二傻,戴着一个草帽,草帽上有一个2字,号称会把一到二号盘搬到任意柱。你灵机一动,问道:“你该不会有个兄弟叫三傻吧?”“对对,老爷你咋知道的?他会搬一到三号盘。“”那你去把他叫来,我不需要你了。“于是三傻来了,他也带着个草帽,上面有个3字。你说:”三傻,你帮我把头三个盘子移到c柱吧。“三傻沉吟了一会,走进树林,你听见他大叫:”二傻,出来帮我把头两个盘子搬到C!“由于天气炎热你开始打瞌睡。朦胧中你没看见二傻是怎么工作的,二傻干完以后,走入林中大叫一声:“老三,我干完了!”三傻出来,把三号盘从A搬到B,然后又去叫二傻:“老二,帮我把头两个盘子搬回A!”余下的我就不多说了,总之三傻其实只搬三号盘,其他叫二傻出来干。最后一步是三傻把三号盘搬到C,然后呼叫二傻来把头两个盘子搬回C事情完了之后你把三傻叫来,对他说:“其实你不知道怎么具体一步一步把三个盘子搬到C,是吧?”三傻不解地说:“我不是把任务干完了?”你说:“可你其实叫你兄弟二傻干了大部分工作呀?”三傻说:“我外包给他和你屁相干?”你问到:“二傻是不是也外包给了谁?“三傻笑了:“这跟我有屁相干?”你苦苦思索了一夜,第二天,你走入林中大叫:“十傻,你在哪?”一个头上带着10号草帽的人,十傻,应声而出:“老爷,你有什么事?”“我要你帮把110号盘子搬到C柱““好的,老爷。“十傻转身就向林内走。“慢着,你该不是回去叫你兄弟九傻吧““老爷你怎么知道的?““所以你使唤他把头九个盘子搬过来搬过去,你只要搬几次十号盘就好了,对吗?““对呀!““你知不知道他是怎么干的?““这和我有屁相干?“你叹了一口气,决定放弃。十傻开始干活。树林里充满了此起彼伏的叫声:“九傻,来一下!“ “老八,到你了!““五傻!。。。“”三傻!。。。“”大傻!“你注意到大傻从不叫人,但是大傻的工作也最简单,他只是把一号盘搬来搬去。若干年后,工作结束了。十傻来到你面前。你问十傻:“是谁教给你们这么干活的?“十傻说:“我爸爸。他给我留了这张纸条。”他从口袋里掏出一张小纸条,上面写着:“照你帽子的号码搬盘子到目标柱。如果有盘子压住你,叫你上面一位哥哥把他搬走。如果有盘子占住你要去的柱子,叫你哥哥把它搬到不碍事的地方。等你的盘子搬到了目标,叫你哥哥把该压在你上面的盘子搬回到你上头。“你不解地问:“那大傻没有哥哥怎么办?“十傻笑了:“他只管一号盘,所以永远不会碰到那两个‘如果’,也没有盘子该压在一号上啊。”但这时他忽然变了颜色,好像泄漏了巨大的机密。他惊慌地看了你一眼,飞快地逃入树林。第二天,你到树林里去搜寻这十兄弟。他们已经不知去向。你找到了一个小屋,只容一个人居住,但是屋里有十顶草帽,写着一到十号的号码。**

青蛙跳台阶问题

一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法

 /**
     *青蛙跳台阶问题(提示, 使用递归)
     * 一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级
     * 求该青蛙跳上一个n 级的台阶总共有多少种跳法
     * 1    1                   1
     * 2    1
     *      2                   2
     * 3    1   1   1
     *      1   2
     *      2   1               3       2+1
     * 4    1   1   1   1
     *      1   2   1
     *      2   1   1
     *      1   1   2
     *      2   2               5       3+2
     *5     1   1   1   1   1
     *      1   2   2
     *      2   1   2
     *      2   2   1
     *      1   1   2   1
     *      1   1   1   2
     *      2   1   1   1
     *      1   2   1   1       8       5+3
     *从3层台阶开始,跳出的方法总等于前两次方法相加
     * n层台阶时的方法=n-1层方法 + n-2层方法
     */
public static int jump(int n) {
    if(n <= 0){
        return 0;
    } else if(n == 1 || n == 2) {
        return n;
    }
    return jump(n - 1) + jump(n - 2);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

twelve1959

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值