递归(汉诺塔问题)(1)

一.题目

面试题 08.06. 汉诺塔问题 - 力扣(LeetCode)

二.思路讲解

2.1 思路讲解

现在我们理解递归,就采取宏观理解递归 的方法来解决这题。首先,用上节课说的从小方面找规律,帮助我们理解大问题如何拆成小问题!

  • 当只有一个盘子的情况下,我们是不是可以直接把 A 上的盘子直接移到 C 里面即可。

  • 当有两个盘子的情况下,我们是不是需要先把 A 的第一个盘子移到 B ,然后再把第二个盘子从 A 移到 C ,最后再把 B 的盘子移到 C

  • 当有三个盘子的情况下,我们要想把第三个盘子移到 C,那么是不是先把第一和第二个盘子移到 B,然后就能把第三个盘子移到 C,最后再把 B 的两个盘子移到 C。

但是,怎么能移动两个盘子呢?直接移不合法。因此我们要把移动两个盘子变成合法的,这不就回到了只有两个盘子的情况 吗?只不过这次是让盘子从 A 移到 B,不再是 A 移到 C,因此我们的目标柱变成了 B ,而 C 变成了中转站(辅助柱)

那如果有四个盘子,不也是先把前三个盘子移到 B,然后最后一个移到 C,接着处理三个盘子------这不就又回到了只有三个盘子的情况吗?如此层层递进,就形成了递归的规律。

三.代码演示

cpp 复制代码
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个盘子移到B柱借用C柱子
        dfs(A,C,B,n - 1);

        //2.把A中第n个盘子移动到C柱子
        C.push_back(A.back());
        A.pop_back();

        //3.把B中n-1个盘子移动到C柱子借用A柱子
        dfs(B,A,C,n-1);
        
    }
};

四.代码讲解

一、递归函数设计

我们定义一个递归函数 dfs(A, B, C, n) ,它的含义是:将柱子 A 上的 n 个盘子,借助辅助柱子 B ,全部移动到目标柱子 C 上。这里 ABC 分别对应三个柱子的数组引用,直接操作原数组。

二、递归终止条件

n == 1 时,说明只剩下一个盘子需要移动。此时,直接将 A 的最后一个盘子(即栈顶)取出,放入 C 中,然后从 A 中移除该盘子。这个操作是直接可行 的,也是递归的最小子问题

三、递归步骤分解

对于 n > 1 的情况,我们将问题分解为三个子步骤,这正是汉诺塔问题的核心规律:

  1. 将 A 上的 n-1 个盘子借助 C 移动到 B 调用 dfs(A, C, B, n - 1)。这一步的目标是把除了最底下那个最大的盘子之外的所有盘子,从 A 移到 B,期间可以借助 C 作为辅助。此时,B 成为这些盘子的目标柱,C 是辅助柱。

  2. 将 A 上剩下的第 n 个盘子直接移动到 C 此时 A 上只剩下最大的那个盘子,直接将其从 A 的末尾取出,放入 C 的末尾,并从 A 中删除。这个操作是单步移动,无需借助其他柱子。

  3. 将 B 上的 n-1 个盘子借助 A 移动到 C 调用 dfs(B, A, C, n - 1)。现在,所有较小的盘子都在 B 上,我们需要把它们再移到 C 上,此时可以借助 A 作为辅助柱。这一步完成后,所有盘子都按顺序移到了 C。

四、关键细节
  • 宏观理解 :我们不必纠结于每一步具体如何移动,只需相信递归函数能完成它的任务 。例如,dfs(A, C, B, n-1) 一定能把 A 上的 n-1 个盘子正确移到 B,至于它内部怎么做的,我们暂时不用管。

  • 参数顺序 :递归调用时,柱子的角色会发生变化。注意每次调用时,三个参数的顺序对应着源柱、辅助柱、目标柱 。例如 dfs(A, C, B, n-1) 表示从 A 移到 B,C 是辅助。

  • 数组操作 :这里用 push_backpop_back 模拟盘子的取出和放入,每个柱子就是一个栈,后进先出,符合汉诺塔规则。

相关推荐
松☆1 天前
C++ 算法竞赛题解:P13569 [CCPC 2024 重庆站] osu!mania —— 浮点数精度陷阱与 `eps` 的深度解析
开发语言·c++·算法
(Charon)1 天前
【C++/Qt】C++/Qt 实现 TCP Server:支持启动监听、消息收发、日志保存
c++·qt·tcp/ip
kronos.荒1 天前
图论——求孤岛面积、淹没孤岛(python)
python·深度优先·图论
jr-create(•̀⌄•́)1 天前
正则化和优化算法区别
pytorch·深度学习·神经网络·算法
EnglishJun1 天前
ARM嵌入式学习(二十三)--- I2C总线和SPI总线
arm开发·学习
饭后一颗花生米1 天前
2026 AI加持下前端学习路线:从入门到进阶,高效突破核心竞争力
前端·人工智能·学习
北山有鸟1 天前
【学习笔记】MIPI CSI-2 协议全解析:从底层封包到像素解析
linux·驱动开发·笔记·学习·相机
并不喜欢吃鱼1 天前
从零开始C++----七.继承及相关模型和底层(上篇)
开发语言·c++
li星野1 天前
刷题:数组
数据结构·算法
YCY^v^1 天前
PSW、PFW、SPSW、SPFW 是信捷TouchWin
学习