汉诺塔问题 [递归 + 抽象]
汉诺塔
- 前言
- 一、题意
- 二、抽象思维
- 1、源码
- 三、扩展
- 1、分析
- 2、源码
- 总结
- 参考文献
前言
汉诺塔问题,是学习递归的第一个算法题,也是非常经典的递归问题。由于它是双递归问题,所以初学时不易理解。但只要带着抽象的思考方式去分析,就能很容易理解多递归问题。
一、题意
二、抽象思维
模拟合法的搬盘子,
- 当A上只有一个盘子时,只需将其搬到目标柱C上;
- 当A上有两个盘子时, 需要先借助B柱来过度,先将小盘子放到B柱上,再将大盘子放到C柱上,最后将B柱上的小盘放到C柱上。仅仅需要三步,就完成了A柱上的两个盘子放到了目标柱C盘上。
- 当盘子有N > 2时,实际可抽象为情况2,底下最大的为一个,上面N-1个小盘为一组,看成一个,就抽象为了情况2。
1、源码
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {int n = A.size();hanota(A,B,C,n);}public void hanota(List<Integer> A, List<Integer> B, List<Integer> C,int n){// 只有一个盘子了,将A中盘子移到C中即可。// 情况1:只有一个盘子,只有一个步骤,moveAtoC()if(n == 1){moveAtoC(A,C);return;}// 先将A中的后n-1个递归移到B中;再将A中最后一个移到C中;再把B中的所有移到C中。// 情况2:有2个盘子 / 抽象为2个盘子,仅仅只需三步。hanota(A,C,B,n - 1);// step1:把上面n-1小的移到B上。moveAtoC(A,C);// step2:把底下最大的移到C上。hanota(B,A,C,n - 1);// 把B的所有盘子即那n-1个,全部移到C上,完成移动了。// 注:这里直接把n-1个盘子直接移到另一个柱子,是目标,而不是实际移动,实际移动是调了函数进行递归,最终走向两盘情况。}public void moveAtoC(List<Integer> A,List<Integer> C){int val = A.get(A.size() - 1);C.add(val);A.remove(A.size() - 1);}
三、扩展
平时多刷题,就是从多个题中抽出共性,那就是题目的本质,需要学习到的知识点。
通过扩展题的方式,探寻汉诺塔的本质。
额外限制,
每次移动只能移动到旁边的柱子,即A柱盘子一步情况下,只能移到B柱,而B柱的盘子可以一步移到左右的A&C柱,而C柱的盘子只能一步移到B柱上。
1、分析
掌握汉诺塔的本质,就是抽象过程,N>1抽象为情况2,N=1为情况1,分情况讨论。
- 当只有一个盘子时,A->B,B->C,移动两次即可。
- 当有两个盘子时, n-1块小盘移动到B,再将B上n-1块小盘移动到C,再将A的大盘移动到B,最后将C盘的n-1移到B上。
柱:如果目标柱是B柱,就完毕了;如果是C柱,那还得将B上的所有盘子转到C上,不过都同理。
2、源码
public int hanota(int n) {return hanota(n,0,1,2);}public int hanota(int n,int a,int b,int c){// 只有一个盘子了,将A中盘子移到C中即可。// 但是只能相邻移动,需要看a 和 c的差距。if(n == 1){return Math.abs(a - c);// 移两次,因为先移动旁边,再移到旁边的另一旁。}// 如果此时的a在中间,将n-1个盘子移到左边,底盘移到右边,而n-1个需搬回原柱,再搬到右边去。// 如果此时的a在左边,将n-1个盘子移到B,再移到C,将底盘放到B,将C的n-1个移到B.// 如果此时的a在右边,将n-1个盘子移动到B,再移动到C,将底盘放到B,最后把n-1移回来。if(a == 0 || a == 2) return hanota(n - 1,a,c,b) + hanota(n - 1,b,a,c) + 1+ hanota(n - 1,c,a,b);if(a == 1)return hanota(n - 1,a,b,c) + 1 + hanota(n - 1,c,a,b);}
总结
1)汉诺塔作为递归的入门经典算法,本质是递归,而递归代码精简,那么对抽象能力考察就比较高。
参考文献
[1] LeetCode 汉诺塔
汉诺塔问题 [递归 + 抽象]相关推荐
- 汉诺塔——经典递归问题(c语言实现)
汉诺塔--经典递归问题(c语言实现) 问题背景 汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下 ...
- 数据结构与算法—递归算法(从阶乘、斐波那契到汉诺塔的递归图解)
目录 递归介绍 递归求阶乘 递归求斐波那契 递归解决汉诺塔 总结 递归介绍 递归:就是函数自己调用自己. 子问题须与原始问题为同样的事,或者更为简单: 递归通常可以简单的处理子问题,但是不一定是最好的 ...
- 【恋上数据结构】递归(函数调用过程、斐波那契数列、上楼梯、汉诺塔、递归转非递归、尾调用)
递归(Recursion) 什么是递归? 函数的调用过程(栈空间) 函数的递归调用过程 递归实例分析(1 + 2 + 3 + ... + 100 的和) 递归的基本思想.使用套路 斐波那契数列 fib ...
- 汉诺塔的递归逐步详解
文章目录 汉诺塔介绍 递归代码实现 以三个盘子为例逐步详解 汉诺塔介绍 如上图,有三根柱子A,B,C,在A柱子上有N个盘子(图上只画了三个),利用这三根柱子和N个盘子进行汉诺塔游戏,需要最终将A柱子上 ...
- 汉诺塔的递归实现,看完就懂了
对于要实现汉诺塔递归程序的同学,我相信有一部分同学还没有真正的玩过汉诺塔这个游戏,我建议先在手机应用商店下载一个汉诺塔游戏去感受一下,当了解了游戏的玩法之后,也更方便你去理解递归代码的逻辑. 下面通过 ...
- 1-算法-hanoi汉诺塔问题- 递归
汉诺塔问题用递归解决 问题抽象 递归都是从最原始的地方回溯 到解决这个大问题 Void hanoi(int n,char A,char B,char C) {if(n == 1) move(1,A,C ...
- labview求n阶乘的和_递归算法(从阶乘、斐波那契到汉诺塔的递归图解)
递归介绍 递归:就是函数自己调用自己. 子问题须与原始问题为同样的事,或者更为简单: 递归通常可以简单的处理子问题,但是不一定是最好的. 对于递归要分清以下概念: 自己调用自己 递归通常不在意具体操作 ...
- 汉诺塔问题递归算法python代码_[python]汉诺塔问题递归实现
一.问题描述及算法步骤 汉诺塔问题的大意是有三根柱子a, b, c,现在a柱有N个盘子从下往上尺寸递减排列,要求: 1. 将a上的盘子移动到c柱上; 2. 每次移动一个盘子; 3. 柱子上的盘子始终必 ...
- python面向过程实践汉诺塔_递归汉诺塔-和递归汉诺塔相关的内容-阿里云开发者社区...
多柱汉诺塔最优算法设计探究 多柱汉诺塔最优算法设计探究 引言 汉诺塔算法一直是算法设计科目的最具代表性的研究问题,本文关注于如何设计多柱汉诺塔最优算法的探究.最简单的汉诺塔是三个柱子(A.B.C),因 ...
最新文章
- Ajax Toolkit 控件学习系列(13) ——FilteredTextBoxExtender 控制输入
- 分布式服务跟踪及Spring Cloud的实现
- Android HttpClient post MultipartEntity - Android 上传文件
- Kafka 基本原理
- zookeeper入门系列
- 最热开源静态网站生成器 TOP 20
- Go 编程怎么也有踩内存?
- Qt总结之十三:QUDPSocket详解
- 火力全开,同时分解(切脸)多个视频
- 微信unionID和openID区别
- 【JavaScript 生成uuid】——用js生成uuid
- 计算机应用数值换算,单位换算计算器完整版
- classes是什么意思怎么读_Classes是什么意思_Classes的翻译_音标_读音_用法_例句_爱词霸在线词典...
- OpenShift免费空间申请使用教程
- z77主板升级nvme,迁移系统,蓝屏解决方法
- 接着,运营基础知识(福利篇)
- 17个练习自动化测试的网站,相信你一定喜欢
- Intel系统编程指南第八章——8.4 多处理器(MP)初始化
- 多商户发卡宝自动发卡系统源码
- 截至2017年1月59家金融租赁公司
热门文章
- Android监听剪贴板来源,Android如何从剪贴板上获取字符串onPrimaryClipChanged?
- 对于DNF强化操作的个人写法(有待改进)
- BERT 论文精读与理解
- 潘正磊 再过三五年 AI会变成开发人员的基本概念
- java动态数组简介_Java动态数组
- 预制菜“虚火太旺”,或重蹈“人造肉”覆辙 | 钛媒体深度
- eclipse安装tomcat
- 业火燃尽这片幽暗荒野 世界终将翻开新一页
- 聚观早报 |中国企业成世界杯最大金主;马斯克恐失去世界首富位置
- 以太坊源码之『RLP』