位置: 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语言中如何防止函数重名)

  • 计提增值税比实际缴纳多
  • 临时性雇佣人员是指
  • 交所得税用计提吗
  • 工商股权转让费用怎么算
  • 金税四期查到了怎么办
  • 残保金上年在职职工工资总额怎么填
  • 固定资产缩水
  • 接受原材料投资的会计处理
  • 一般纳税人公司是什么型企业
  • 应收留抵税额退税款科目是资产类
  • 营改增医院增值税
  • 开增值税发票开户行怎么填?
  • 城建税和教育费附加的计税依据是什么
  • 公司房产税如何计算器
  • 红字发票打印乱码怎么办
  • 分公司负债,总公司要负担
  • 生育津贴需要缴纳五险一金吗
  • 劳务派遣用工工资标准
  • 购买债券投资的交易费用
  • 企业停产没有收入,费用可以计入长期待摊费用吗
  • 诉讼费计入哪里
  • 所得税招待费用
  • 银行承兑汇票背书会计分录
  • 税金及附加怎么登明细账
  • 事业单位在建工程转固定资产的账务处理
  • 广告制作费属于劳务还是服务
  • 物业公司营业成本包括哪些
  • win7系统为什么没有虚拟光驱
  • win10投影无反应
  • 冈山平原
  • apache配置多个项目
  • 现金收入如何做账务处理
  • 结算应付职工薪酬怎么算
  • 上年未结转的成本今年可以结转吗
  • php分类信息
  • yolov1 实现
  • Chatgpt私有化部署(全流程)
  • 基本户 变更
  • 织梦自定义模型调用
  • 织梦设置的关键词看不到
  • 开始送加盟费
  • 电子发票能退回去吗
  • 财政借钱给预算单位的会计处理
  • 一般计税预缴增值税2%怎么算
  • 企业计提固定资产折旧以什么假设为前提
  • 资产负债表没有
  • 公司账户转到公司账户要多久
  • 融资租赁租出的固定资产账务处理
  • 技术报酬金是什么意思
  • 固定资产无形资产处置损益计入
  • 购买农副产品抵扣进项税的规定
  • 异地工程可以在公司所在地缴纳税款吗
  • 资产负债表中应付职工薪酬是负数
  • 从公账提取备用金到个人账户怎么做会计分录
  • 小规模纳税人不超过10万免增值税
  • 本期应征增值税销售额是什么意思
  • 发票邮寄到家
  • 工程施工和主营业务成本关系
  • SQL server字符串存数据库大还是二进制大
  • CentOS7下MySQL5.7安装配置方法图文教程(YUM)
  • win8换win7详细过程
  • win10虚拟桌面版
  • windows xp.
  • ghost后不能启动
  • win10预览版和正式版
  • 苹果Mac系统怎么安装
  • 开机记事本自动打开
  • win7系统代理在哪里设置
  • 笔记本win7电源已接通未充电怎么办
  • win8.1怎么重新装系统
  • 一个简单的灵魂福楼拜
  • js原型继承和构造继承
  • Unity3D游戏开发标准教程
  • 深入理解javascript特性.pdf
  • jquery获取单选按钮的值
  • 哪些润滑油属于润滑剂
  • 计算消费税为什么要除1-比例税率
  • 小规模纳税人的开票
  • 房子有注册公司可以卖吗
  • 安全生产管理局和应急局
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设