【算法】递归、搜索与回溯——汉诺塔

news2024/11/20 4:49:34

题解:汉诺塔(递归、搜索与回溯算法)

目录

  • 1.题目
  • 2.题目背景(拓展了解)
  • 3.题解
  • 4.参考代码
  • 5.细节
  • 6.总结

1.题目

题目链接:LINK
在这里插入图片描述
在这里插入图片描述

2.题目背景(拓展了解)

汉诺塔问题是一个通过隐式使用递归栈来进行实现的一个经典问题,该问题最早的发明人是法国数学家爱德华·卢卡斯。

汉诺塔传说
传说印度某间寺院有三根柱子,上串64个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子;预言说当这些盘子移动完毕,世界就会灭亡。这个传说叫做梵天寺之塔问题(Tower of Brahma puzzle)。但不知道是卢卡斯自创的这个传说,还是他受他人启发。若传说属实,僧侣们需要2^64 − 1步才能完成这个任务;若他们每秒可完成一个盘子的移动,就需要5845亿年才能完成。整个宇宙现在也不过137亿年。这个传说有若干变体:寺院换成修道院、僧侣换成修士等等。寺院的地点众说纷纭,其中一说是位于越南的河内,所以被命名为“河内塔”。另外亦有“金盘是创世时所造”、“僧侣们每天移动一盘”之类的背景设定。佛教中确实有“浮屠”(塔)这种建筑;有些浮屠亦遵守上述规则而建。“汉诺塔”一名可能是由中南半岛在殖民时期传入欧洲的。
在这里插入图片描述

与之相似的一个故事就是“棋盘放大米的故事”:
故事是这样的,最初一位大哥发明了一种玩具叫做围棋,这个围棋有64个格子组成,国王很高兴问发明者什么赏赐,发明者说到“第一个格子放1粒大米,第二个格子放2粒大米,第三个格子放4粒大米,此后每个格子都是前面的两倍大米,放满棋盘上的64个格子就好”,随后国王欣然接受,然而经过实践,即使把整个王国的大米搬过来放,也不能放满64个棋格。
在这里插入图片描述

这两个故事都揭示了一个道理——指数大爆炸

3.题解

我们枚举不同N情况下移动过程如下:
在这里插入图片描述
写递归的步骤
在这里插入图片描述

  • 函数头的设计
    除N = 1,情况外,所有N的情况都可以分为三步,即先把A柱上的前N-1个盘子放到B柱上,再把A柱的最下面一个盘子放到C上,再把B柱上的盘子放到C上。
    所以,解决此问题,我们只需要接受A、B、C、N的个数即可。

  • 函数体的设计
    先把A柱上的N-1个盘子放到B柱上,再把A的最下的一个盘子放到C上,再把B上的N-1个盘子放到C上。

  • 函数结束
    当N = 1时,不再满足上述三步走规律,只需要把那个盘子放到C上即可。

4.参考代码

class Solution {
public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) 
    {
        dfs(A,B,C,A.size());
    }

    void dfs(vector<int>& A, vector<int>& B, vector<int>& C,int n)
    {
        //出递归
        if(n == 1)
        {
            C.push_back(A.back());
            A.pop_back();
            return;
        }

        //1.先把A中的N-1个盘子借助C扔到B上
        dfs(A,C,B,n-1);
        //2.再把A中剩下的一个盘子扔到C上
        C.push_back(A.back());
        A.pop_back();
        //3.再把B中的N-1个盘子借助A扔到C上
        dfs(B,A,C,n-1);
    }
};

5.细节

思考:
如果我们把代码C.push_back(A.back())改成C.push_back(A[0])可以吗?为什么?

答:不行。 因为我们思考顺序与实际挪动顺序不一致。
虽然我们直觉上认为A.back()与A[0]在只剩下一个元素时候都表示的是最后的那个盘子,但是计算机运行的顺序跟我们脑子想的顺序并不一致,计算机先从最小的子问题(不可分割)的情况开始运算,而我们想的是先从最大问题的那个开始思考。
在只剩下一个元素的情况下A[0]和A.back()的确是一样的,但是计算机运行的时候并不是只有一个元素!!!

举个例子:
在这里插入图片描述

6.总结

汉诺塔作为经典的简单递归题目,是需要好好理解的,比如我上面提到的写递归的步骤以及为什么A.back()不能写成A[0]的问题。


EOF

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1707432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux系统——bg命令,linux运行的级别

在linux中可以使用bg命令&#xff0c;将进程任务置于后台执行 在这里&#xff0c;使用ping www.baidu.com命令后再使用ctrlz&#xff0c;可以将命令先暂停并保留在后台&#xff0c;jobs可以对任务进行查看 使用runlevel可以查看系统当前的运行级别

解决npm卡死,无法安装依赖

npm卡死&#xff0c;无法安装依赖 异常描述原因分析与解决方法 异常描述 1.无法进入命令行&#xff0c;或是很慢没反应 2.装表格无限滚动的el-table-infinite-scroll依赖一上午了&#xff0c;也不能装&#xff0c;报错提示 原因分析与解决方法 1.命令行的问题&#xff1a;缓…

【头歌】计算机网络DHCP服务器配置第二关access口配置答案

头歌计算机网络DHCP服务器配置第二关access口配置操作步骤 任务描述 本关任务&#xff1a;创建 vlan &#xff0c;并且将与 pc 机相连接口划分 vlan 。 操作要求 在第一关的拓扑图的基础上&#xff0c;配置交换机&#xff0c;具体要求如下&#xff1a; 1、在特权模式下进入 vla…

开源VS闭源:谁更能推动AI技术的普及与发展?

一、引言 在人工智能&#xff08;AI&#xff09;技术的浪潮中&#xff0c;开源与闭源两种模式一直并存&#xff0c;并各自在推动AI技术普及与发展上发挥着重要作用。然而&#xff0c;关于哪种模式更能有效地推动AI技术的普及与发展&#xff0c;一直存在着激烈的讨论。本文将深…

【前端工程化指南】Git常见操作之协作相关操作

获取远程仓库的更新 我们可以使用 git fetch 或者 git pull 两个命令从远程仓库获取最新的提交和分支信息&#xff0c;两者区别如下&#xff1a; git fetch&#xff1a;该命令将远程仓库的最新更改下载到本地&#xff0c;但不会自动合并到当前分支。你可以随后使用其他命令&a…

电子围栏(地理围栏)设计逻辑

做完整的项目时需要考虑安全问题&#xff0c;判断车辆在不该出现的位置出现时自动刹车。 只能说可以有吧。 地理围栏的概念 自动驾驶地理围栏是指在自动驾驶系统中定义的一种虚拟边界&#xff0c;用于限制车辆的运行范围。地理围栏可以通过全球定位系统&#xff08;GPS&#…

超详细Lambda表达式与Stream流及Maven环境搭配

目录 1.什么是Lambda表达式 2.为什么使用Lambda表达式 3.Lambda表达式语法 4.语法糖 5.Stream流 5.1stream流是什么 特点 5.2为什么要用Stream 5.3Stream流中的静态方法 6.Maven(项目编译打包软件) 6.1什么是Maven 6.2为什么要使用Maven 6.3Maven 中的相关概念 6.…

Android应用开发之AndroidManifest.xml

一.AndroidManifest.xml介绍 1.定义 AndroidManifest官方解释是应用清单&#xff08;manifest意思是货单&#xff09;&#xff0c;每个应用的根目录中都必须包含一个&#xff0c;并且文件名必须一模一样。 它是Android程序的全局配置文件&#xff0c;是每个 android程序中必须…

Java入门基础学习笔记45——String使用的注意事项

String使用时的注意事项&#xff1a; 1&#xff09;String对象的内容不可改变&#xff0c;被称为不可变字符串对象。 Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are im…

最新百度专用站群seo官网程序源码二级泛程序

发布站专用站群SEO推广网站源码支持泛解析无限扩张功能&#xff1a; 1、支持伪静态功能&#xff0c;减少生成静态页增加网站内容&#xff0c;比动态网站更有利于网站收录。 2、支持百度seo优化效果&#xff0c;主动提交百度收录&#xff0c;可生成sitemap.xml文件提交百度减少…

企业内网终端监控管理软件有哪些?推荐4款企业终端监控管理软件

企业内网终端监控管理软件是一种专为企业内部网络设计的安全与管理工具&#xff0c;旨在帮助企业管理、监控和保护其内部网络中的各种终端设备&#xff0c;如个人电脑、笔记本、移动设备等。 这类软件的主要功能包括但不限于以下几个方面&#xff1a; 1&#xff0c;实时监控&a…

总结常见漏洞的代码审计方法

前言 这篇文章主要是总结一下在安全工作中常见漏洞的代码审计方法&#xff0c;以及修复方案&#xff0c;希望能对初学代码审计小伙伴们有所帮助&#xff0c;笔芯♥️ 代码审计的思路 通常做代码审计都是检查敏感函数的参数&#xff0c;然后回溯变量&#xff0c;判断变量是否可…

探索Solana链上DApp开发:高性能区块链生态的新机遇

Solana 是一个新兴的区块链平台&#xff0c;致力于为 DApp&#xff08;去中心化应用程序&#xff09;开发者提供高性能、低成本的解决方案。Solana 的独特之处在于其创新性的共识机制和高吞吐量的网络&#xff0c;使得开发者可以构建高度可扩展的 DApp&#xff0c;并为用户提供…

如何在Python 中如何导入和引用外部文件(Colab VS Code)

1. 上传文件 在 Google Colab 中&#xff0c;从左侧界面的文件选项中使用 "Upload" 按钮上传文件。 在 VS Code 中&#xff0c;通过菜单栏中的 "File" -> "Open File/Folder" 选项上传文件&#xff08;建议将所有文件放入一个文件夹中&#…

Linux--进程间通信(2)(有名管道)

目录 1.原理 2.创建命名管道 3.使用命名通道实现简单的通信 4.使用创建的命名管道 1.原理 匿名管道没有名称&#xff0c;它们是通过句柄在父进程和子进程之间传递的。这意味着匿名管道只能用于具有父子关系的进程之间。 但如果程序之间没关系&#xff0c;那么这时候就要用…

向传音手机学习产品市场定位与产品需求定义

2024 年第一季度全球智能手机发货量同比增长 11%&#xff0c;排在第一名的是三星&#xff0c;占比 21%&#xff0c;苹果占比 17% 排在第二位&#xff0c;小米 14%排在第三名&#xff0c;传音手机10% 排在第四位&#xff0c;OPPO为 9% 排在第五名。 「非洲之王」传音手机表现十…

增强创作者能力:The Sandbox 首届 “创作者挑战” 回顾

首届 "创作者挑战" 为创作者在平台上赚取收入提供了难得机会。 我们发起 “创作者挑战” 的目的是支持创作者&#xff0c;赋予他们构建元宇宙的能力。我们提出三大行动号召&#xff1a;发布、参与和赚钱。新推出的「参与奖池」&#xff08;Engagement Pool&#xff0…

灵动微单片机洗衣机方案——【软硬件开发支持】

RAMSUN英尚以洗衣机洗涤主驱电机为例&#xff0c;主驱电机和多电机控制首选MM32SPIN0280.灵动微电子能够提供完整的软硬件开发支持&#xff0c;目前方案已经在主流家电厂出货。 洗衣机方案 皮带洗衣机 DD直驱洗衣机 波轮洗衣机 Mini壁挂和桌面洗衣机 洗涤烘干双变频方案 热泵烘…

【机器学习】利用机器学习优化陆军战术决策与战场态势感知

&#x1f512;文章目录&#xff1a; &#x1f4a5;1.引言 &#x1f6f4;2.机器学习在陆军战术决策中的应用 &#x1f6e3;️2.1数据收集与预处理 &#x1f304;2.2模型构建与训练&#xff1a; &#x1f305;2.3实时决策支持&#xff1a; &#x1f305;2.4代码实现 &…

C++学习日记 | LAB 6 static library 静态库

资料来源&#xff1a;南科大 余仕琪 C/C Program Design LINK&#xff1a;CPP/week06 at main ShiqiYu/CPP GitHub 一、本节内容 本节主要介绍静态库和动态库。 1.1 静态库和动态库的概念 静态链接和静态库(也称为存档)是链接器将所有使用的库函数复制到可执行文件的结果。静…