java 河内塔问题,java 汉诺塔问题 递归

题目链接

https://leetcode-cn.com/problems/hanota-lcci/

题目介绍

面试题 08.06. 汉诺塔问题

在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:

(1) 每次只能移动一个盘子;

(2) 盘子只能从柱子顶端滑出移到下一根柱子;

(3) 盘子只能叠在比它大的盘子上。

请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。

你需要原地修改栈。

示例1:

输入:A = [2, 1, 0], B = [], C = []

输出:C = [2, 1, 0]

解题思路

其实汉诺塔问题,就是一个递归问题。

递归的思想很重要,假如把这个问题分解成一个很小的问题,我该怎么做。那么,如果小问题能解决,那么这个问题在哪个地方进行了复杂化

因为无论是大问题还是小问题,它们往往共享着同一个本质内核,而那往往也是解决问题的关键。

A:1个。你会如何做?直接拿过去,很简单!

A:2个。复杂点了,刚刚我们已经解决了一个了,那我们能不能把这个问题转换为1个呢?把A的一个拿到B上,那么问题就迎刃而解了。

A:3个。更复杂了,那我们能不能也像之前一样,把A变成1个呢?把A上面2个拿到B上,那么A不就剩下1个了。再把B上的两个拿过去不就结束了。(可以类比一下A:2个的情况,只是变成了B到C,A是过渡的柱子)

7468b56f538249a139cd53b698afc53f.png

2289790ca49f5b69683c665a058f7626.png

f930047b80bfd8d951b80fbce225ffdc.png

e8b688edeab4480ef6f833b7d2a448a0.png

class Solution {

public void hano(int n,List A, List B, List C) {

// 基例 A上只有一个

if (n == 1) {

C.add(A.remove(A.size() - 1)); // A别忘了清空

return; //不返回值,但是会中断下面进程

} else {

hano(n-1,A,C,B);

hano(1,A,B,C);

hano(n-1,B,A,C);

}

}

public void hanota(List A, List B, List C) {

hano(A.size(),A,B,C);

}

}

最优解

其实很多时候,想要有本质上的突破,应该回到最初的地方,换个角度思考,再一次从山脚重新出发,其实这个问题不就是让我把A里的全给C嘛!很简单!

class Solution {

public void hanota(List A, List B, List C) {

for (Integer i:A) {

C.add(i);

}

}

}

拓展提升

其实很多时候学算法,但算法又是什么,算法不是凭空捏造的,若算法成了纯理论,它将不复有意义,算法是为了解决实际问题而设计的,说白了,与那些数学物理的思想有什么大的区别呢?就比如这道题,数学物理和算法的区别好比是python和java解决问题一样。

既然如此,很多时候遇到新的问题,不妨联想类比一下新的思想,我一直都相信,真正好的方法绝对共通的,只是可能表达形式不一样,正是这些基础的好方法构成了林林总总的方法论。

就拿这个递归来讲,其实不就是将问题转换为最简单,我们已知的可以解决的问题吗?

数学上当你学习新的理论的时候,数学老师总会说把这个陌生的问题转换为已知的问题去解决,然后用已知的推未知的

物理当你学变速运动,你不用记很多公式,你只需要记得加速度对时间的二阶导数是位移,其他你通过积分,转换就可以出来

算法上抛开本题,还有一类题目叫做动态规划,里面会有记事本,换了个名字,其实不就是记录下来我们已知的可以解决的问题吗?

当你学的越多,你可以思考的维度就越多,而当你把这一切联系起来的时候,一切都会不同。

Simple is the best!

大家觉得我写的好,可以关注我的Github,近期会一直更新java。

https://github.com/sherlcok314159/leetcode-java/blob/main/md/hano.md

标签:柱子,java,递归,List,问题,算法,汉诺塔,hano,盘子

来源: https://blog.csdn.net/qq_50974223/article/details/114376711

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值