方法递归练习,基础小白必看

☀️前言☀️

本篇文章给大家讲解递归入门的经典习题之求斐波那契数列、青蛙跳台阶、汉诺塔。

👦有缘,才相遇,你好!我是hgway_hxz

❤️热爱Java,希望结识更多的小伙伴一起交流

🎉欢迎大家:👍点赞 💬评论 ⭐收藏 💖关注

✉️如果有任何问题欢迎大家在评论区讨论或者私信我

✏️只要敢于拼搏,失败也是一种欣慰

🔓1.求斐波那契数列的第 N 项

**斐波那契数列**指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89…这个数列从第3项开始,每一项都等于前两项之和。

💡解题思路

我们用递归做,先找出

递归条件:fib(n) = fib(n - 2) + fib(n - 1) (n > 2)

终止条件:n == 1 || n == 2

🔑代码

public static int fib(int n) {
    if (n == 2 || n == 1) {
        return 1;
    }
    return fib(n - 2) + fib(n - 1);

}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    System.out.println(fib(n));
}

如果n的值过大的话,可能会产生过多的冗余计算,浪费计算资源,所以可以用循环迭代做:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ANqUmIvG-1666651997068)(img/斐波那契数列.gif)]

代码

public static int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    int f1 = 1;
    int f2 = 1;
    int f3 = 0;
    for (int i = 3; i <= n; i++) {
        f3 = f1 + f2;
        f1 = f2;
        f2 = f3;
    }
    return f3;
}

🔓2.青蛙跳台阶问题

💡解题思路

(提示, 使用递归) 一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法,跟上题的求斐波那契数列的第 N 项想法一样,类似题目:BC166 小乐乐走台阶

n = 1时, 1种跳法
n = 2时, 2种跳法
n = 3时, 3种跳法	等于前两项之和
n = 4时, 5种跳法
…………

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MfYwZicb-1666651997069)(img/青蛙跳台阶.gif)]

使用递归

我们用递归做,先找出

递归条件:frogJump(n) = frogJump(n - 2) +frogJump(n - 1) (n > 1)

终止条件:n == 1 || n == 2

🔑递归代码

public static int frogJump(int n) {
    if (n == 1 || n == 2) {
        return n;
    }
    return frogJump(n - 1) + frogJump(n - 2);
}

🔑循环代码

public static int frogJump(int n) {
    if (n == 1 || n == 2) {
        return n;
    }
    int f1 = 1;
    int f2 = 2;
    int f3 = 0;
    for (int i = 3; i <= n; i++) {
        f3 = f1 + f2;
        f1 = f2;
        f2 = f3;
    }
    return f3;
}

🔓3.求解汉诺塔问题

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

💡解题思路

有A、B、C三个柱子,我们需要把A柱上的若干个盘子从A柱按照上小下大的顺序移动到C柱上,一次只能移动一个盘子,从上到下盘子的编号为1~n。

当盘子的个数n为1时,盘子从A柱移动到C柱

n = 1,A -> C

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z0QfKK1B-1666651997069)(img/汉诺塔.png)]

当盘子的个数n为2时,盘子从A柱移动到B柱,A柱移动到C柱,B柱移动到C柱

n = 2,A -> B,A -> C,B -> C

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jdNHPJBX-1666651997070)(img/汉诺塔2.png)]

当盘子的个数n为3时,盘子从A柱移动到C柱,A柱移动到B柱,C柱移动到B柱,A柱移动到C柱,B柱移动到A柱,B柱移动到C柱,A柱移动到C柱

n = 3,A -> C,A -> B,C -> B,A -> C,B -> A,B -> C,A -> C

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2j69BW4q-1666651997070)(img/汉诺塔3.png)]

…………

我们发现以下规律:

  • n = 1时,把盘子从A柱移动到C柱
  • n > 1时,把n - 1个盘子从A柱全部移动到B柱,然后盘子A柱移动到C柱

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZ9G6yzh-1666651997070)(img/汉诺塔4.png)]

  • 把n - 1个盘子从B柱全部移动到C柱

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkN6mT8Q-1666651997071)(img/汉诺塔5.png)]

🔑代码

/**
 *  盘子从pos1位置移动到pos2位置
 * @param n 盘子的个数
 * @param pos1  盘子的起始位置
 * @param pos2  盘子的结束位置
 */
public static void move(int n, char pos1, char pos2) {
    System.out.print(pos1 + "->" + pos2 + " ");
}

/**
 *
 * @param n 盘子的个数
 * @param pos1  盘子的起始位置
 * @param pos2  盘子的中转位置
 * @param pos3  盘子的结束位置
 */
public static void hanoi(int n, char pos1, char pos2, char pos3) {
    if (n == 1) {
        move(1, pos1, pos3);
    } else {
        hanoi(n - 1, pos1, pos3, pos2);
        move(1, pos1, pos3);
        hanoi(n - 1, pos2, pos1, pos3);
    }
}

public static void main(String[] args) {
    hanoi(1, 'A', 'B', 'C');
    System.out.println();
    hanoi(2, 'A', 'B', 'C');
    System.out.println();
    hanoi(3, 'A', 'B', 'C');
}

结果:

A->C 
A->B A->C B->C 
A->C A->B C->B A->C B->A B->C A->C 
Process finished with exit code 0
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

那年盛夏繁如花

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

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

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

打赏作者

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

抵扣说明:

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

余额充值