个人心得——hanoi问题 汉诺塔问题详细分析

简单地介绍题目

点进来的各位其实也应该不陌生了,三根柱子,N个圆盘,要求把所有的圆盘从第一根柱子放到第三根上,并且编号下面的圆盘不能放在编号上的圆盘上。这个问题其实知乎上有很多答主都答得不错,这里我想分析一下自己的一些收获。

如何理解hanoi的逻辑

我们都知道,hanoi塔在计算机语言中是一种递归的逻辑。

很多人在关注这种递归的时候往往喜欢一步一步的追踪,以此来弄明白它的内层逻辑,简单地说,就是顺藤摸瓜,一步步推。

但是要想简单快速的理解递归,这种方式是不提倡的。比如这题,O(2*n)的复杂度,4个盘子就够呛。

因为递归本身就是把具体的分析交给计算机去做,程序员只提供解决问题的思路。

递归的要素应该是每一步的思路,以及终止条件的判断。就像物理中,我们只关心物体的速度变化以及停止运动的时间,因为知道这些就可以求出每一时刻物体的位置。

有人说,要相信数学归纳法,我觉得很有道理,因为递归本质上核心就是数学归纳法。

回到正题,hanoi问题,其实可以简化。既然以递归的模式来思考,那就一开始就假设你要移动n个盘子(n是一个比较大的数字),不要去思考前n-1个盘子的具体解决问题,因为你是在递归,只思考过程,不考虑细节。

既然不考虑前n-1个盘子具体怎么移,那我们就可以简单的把它看作一个整体(反正你具体怎么移都不关我事),这个时候你会发现盘子居然只有两个了!

设前n-1个盘子“合成”的大盘子每移动一次消耗a次移动次数,接下来可以很容易的得出一个推论(真相只有一个):

sum=2*a+1;

也就是说,移动第n个盘子只需要把前n-1个盘子移动两次,自己移动一次。

递推逻辑get!

终止条件就简单了,因为所有的递归都是循环,在理解这一步逻辑之后你甚至可以用循环来写。

无非就是从第一个盘子求到第n个盘子嘛~

反手就是一个for循环
sum=1;
for(int i=2;i<=n;i++)
{
sum=2*sum+1;
}

很简单嘛,递归也是同样的道理,从第一个递归到最后一个盘子就结束。

所以当你把每一步的递归逻辑吃透之后,就会很简单。你看,如果不用这种方式,即使只有5个盘子,你要遍历它也得花费不少的时间,而且对解题来说,不理解递归逻辑,就算一层一层推也没有什么帮助。

当然,我也不是全屏否定这种方式,因为它可以帮助我们快速理解一些逻辑,但是解题时,更多还是需要我们去尝试,跳过简单的推导,直接尝试去找程序的逻辑,而不是某一步的结果,这样我们才能更快的解决问题。

总结:hanoi这类的问题有无数个,但是我们解题的核心其实是有相似点的,这种解题收获才是我们刷题的关键。

这就是我从hanoi问题中得到的一些启发吧,希望能够帮到自己,也希望能帮到你们。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值