位置: IT常识 - 正文

汉诺塔问题分治求解(汉诺塔问题动画演示)

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

推荐整理分享汉诺塔问题分治求解(汉诺塔问题动画演示),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:汉诺塔问题解析,汉诺塔问题解析,汉诺塔问题的最佳解决方案,汉诺塔问题总结,汉诺塔问题总结,汉诺塔问题的解决方法,汉诺塔问题分析,汉诺塔问题分析,内容如对您有帮助,希望把文章链接给更多的朋友!

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

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

你需要原地修改栈。

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

解题思路:递归与分治这是一道递归方法的经典题目,乍一想还挺难理清头绪的,我们不妨先从简单的入手。

假设 n = 1,只有一个盘子,很简单,直接把它从 A 中拿出来,移到 C 上;

如果 n = 2 呢?这时候我们就要借助 B 了,因为小盘子必须时刻都在大盘子上面,共需要 4 步。

汉诺塔问题分治求解(汉诺塔问题动画演示)

如果 n > 2 呢?思路和上面是一样的,我们把 n 个盘子也看成两个部分,一部分有 1 个盘子,另一部分有 n - 1 个盘子。

观察上图,你可能会问:“那 n - 1 个盘子是怎么从 A 移到 C 的呢?”

当你在思考这个问题的时候,就将最初的 n 个盘子从 A 移到 C 的问题,转化成了将 n - 1 个盘子从 A 移到 C 的问题, 依次类推,直至转化成 1 个盘子的问题时,问题也就解决了。这就是分治的思想。

而实现分治思想的常用方法就是递归。不难发现,如果原问题可以分解成若干个与原问题结构相同但规模较小的子问题时,往往可以用递归的方法解决。具体解决办法如下:

n = 1 时,直接把盘子从 A 移到 C;

n > 1 时,

先把上面 n - 1 个盘子从 A 移到 B(子问题,递归);

再将最大的盘子从 A 移到 C;

再将 B 上 n - 1 个盘子从 B 移到 C(子问题,递归)。

Java代码class Solution { public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) { /* 1.先将A柱子中的n-1个的圆盘移动到B柱子 2.再将A柱子中最后1个圆盘移动到C柱子 3.最后将B柱子的n-1个圆盘移动到C柱子 */ int n = A.size(); move(n, A, B, C); } /* 其中A为原始柱子;B为辅助柱子;C为目标柱子(与位置有关,那么list都有可能) */ private void move(int n, List<Integer> A, List<Integer> B, List<Integer> C) { // A中只剩下1个圆盘了,直接移动到C柱子后结束 if (n == 1) { C.add(A.remove(A.size() - 1));// 将A柱子中最后1个圆盘移动到C柱子 return; } // 1.先将的A柱子中的n-1个的圆盘移动到B柱子(此时B为目标柱子,A为原始柱子) move(n - 1, A, C, B); // 2.再将的A柱子中最后1个圆盘移动到C柱子 C.add(A.remove(A.size() - 1)); // 3.最后将B柱子的n-1个圆盘移动到C柱子(此时C为目标柱子,B为原始柱子) move(n - 1, B, A, C); }}C++代码class Solution {public: void hanota(vector<int>& A, vector<int>& B, vector<int>& C) { int n = A.size(); move(n, A, B, C); } void move(int n, vector<int>& A, vector<int>& B, vector<int>& C){ if (n == 1){ C.push_back(A.back()); A.pop_back(); return; } move(n-1, A, C, B); // 将A上面n-1个通过C移到B C.push_back(A.back()); // 将A最后一个移到C A.pop_back(); // 这时,A空了 move(n-1, B, A, C); // 将B上面n-1个通过空的A移到C }};复杂度分析时间复杂度:O(2^n-1)。一共需要移动的次数。空间复杂度:O(1)。
本文链接地址:https://www.jiuchutong.com/zhishi/311789.html 转载请保留说明!

上一篇:dedecms织梦Tag标签伪静态设置方法(织梦网站特有标识)

下一篇:c语言中如何防止数组下标越界(c语言中如何防止函数重名)

  • 耕地占用税中的耕地是指什么
  • 小规模纳税人的企业所得税税率
  • 财务报表申报错误怎么办
  • 资产减值损失包括应收账款减值损失吗
  • 其他应付款长期挂账如何处理
  • 房地产公司资本公积
  • 搬家费账务处理
  • 土地使用权出让金多少钱一平米
  • 企业清理固定资产所得税汇算是需要调整吗
  • 付给总机构的管理费可以税前扣除吗
  • 售后回租利息和租金区别
  • 小规模纳税人怎么查询
  • 债务重组损失计算公式
  • 计提增值税怎么计提
  • 免费赠送物业费活动语句怎么写
  • 失业稳岗补贴要交所得税吗
  • 供货方代垫运费计入原材料
  • 民事诉讼的适用范围和基本制度
  • 公司买手机可以开票抵扣吗
  • 电子版A4黑白发票可以抵税吗?
  • 到底如何理解参数方程
  • 什么发票 既可以抵扣又可以退税
  • 以前年度少计提收入
  • 人力资源部报销购买办公家具款
  • 企业所得税法如何确认应税收入
  • cpu天梯图2022最新版1240p
  • 苹果手机怎么刷机
  • 虚拟机vm怎么用
  • vue怎么使用本地存储比较好
  • 会计核算的实训目的
  • 其他应收款期末贷方余额表示什么
  • 物业公司管理制度及工作要求
  • 个体户文化事业建设费免征
  • php自动编号
  • 房产税和城镇土地使用税需要计提吗
  • 第二季度所得税怎么算
  • php如何实现
  • Stable Diffusion 关键词tag语法教程
  • PHP编写1+到100
  • 固定资产投资入股是否缴纳增值税
  • 处置子公司利润表
  • 小规模都是做季报吗
  • 不单独计价的包装物押金计入什么科目
  • 交易性金融资产属于流动资产
  • 带薪休假工资怎么扣税的
  • 补缴的土地价款怎么算费用
  • 水电费分割单能报销吗
  • 固定资产计提折旧的原则
  • 收到政府的资本公积可以投入子公司吗
  • 预收工程款怎么做账
  • 房地产企业所得税税负率是多少
  • 工程挂靠取得的收入怎么做账?
  • 发行长期债券计入什么科目
  • 税控盘服务费抵扣
  • 工程施工和工程造价哪个好
  • win7登录不了系统界面
  • 迁移windows
  • centos 进程查询
  • ubuntu 安装x11
  • mac打开safari快捷键
  • ubuntu怎样调出命令行
  • linux中修改root密码
  • gacrunner.exe是什么
  • win7arm
  • win7怎么打开windows media player
  • js中如何实现数字相加
  • window系统设置
  • perl执行shell命令
  • java script教程
  • 网页css加载失败
  • 如何获得select选中的值
  • Web Inspector:关于在 Sublime Text 中调试Js的介绍
  • vue怎样使用
  • python添加用户并加入到相应组
  • 云南省税务局app缴费
  • 消费税申报详细流程图
  • 网上新办税务操作流程
  • 电脑上怎样安装word文档
  • 财税公众号名称大全
  • 国家税务贵州省税务局
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设