题解 | 汉诺塔问题

解题思路

  1. 递归思想

    • 个盘子的移动分解为三步
    • 先将 个盘子移到中间柱子
    • 再将最大的盘子移到目标柱子
    • 最后将 个盘子从中间移到目标柱子
  2. 基本情况

    • 时,直接移动这个盘子
    • 记录移动步骤
  3. 递归过程

    hanoi(n, from, mid, to):
        if n == 1:
            move disk from 'from' to 'to'
            return
        hanoi(n-1, from, to, mid)
        move disk n from 'from' to 'to'
        hanoi(n-1, mid, from, to)
    

代码

class Solution {
public:
    vector<string> getSolution(int n) {
        vector<string> steps;
        hanoi(n, "left", "mid", "right", steps);
        return steps;
    }
    
private:
    void hanoi(int n, string from, string mid, string to, vector<string>& steps) {
        if(n == 1) {
            steps.push_back("move from " + from + " to " + to);
            return;
        }
        
        hanoi(n-1, from, to, mid, steps);
        steps.push_back("move from " + from + " to " + to);
        hanoi(n-1, mid, from, to, steps);
    }
};
import java.util.*;

public class Solution {
    private ArrayList<String> steps;
    
    public ArrayList<String> getSolution(int n) {
        steps = new ArrayList<>();
        hanoi(n, "left", "mid", "right");
        return steps;
    }
    
    private void hanoi(int n, String from, String mid, String to) {
        if(n == 1) {
            steps.add("move from " + from + " to " + to);
            return;
        }
        
        // 将n-1个盘子从from移动到mid
        hanoi(n-1, from, to, mid);
        // 将第n个盘子从from移动到to
        steps.add("move from " + from + " to " + to);
        // 将n-1个盘子从mid移动到to
        hanoi(n-1, mid, from, to);
    }
}
class Solution:
    def getSolution(self, n: int) -> List[str]:
        steps = []
        
        def hanoi(n: int, fr: str, mid: str, to: str) -> None:
            if n == 1:
                steps.append(f"move from {fr} to {to}")
                return
            
            hanoi(n-1, fr, to, mid)
            steps.append(f"move from {fr} to {to}")
            hanoi(n-1, mid, fr, to)
        
        hanoi(n, "left", "mid", "right")
        return steps

算法及复杂度分析

算法:递归 时间复杂度

  • 每个盘子都需要移动3次
  • 总共有 个盘子

空间复杂度

  • 需要存储所有移动步骤
  • 递归调用栈的深度为

注意事项

  1. 字符串格式

    • 移动描述必须符合要求格式
    • "move from X to Y"
  2. 递归终止条件

    • 时直接移动并记录
  3. 参数传递

    • 需要正确传递三个柱子的名称
    • 保持移动顺序的正确性
全部评论

相关推荐

白火同学:1、简历可以浓缩成一页,简历简历先要“简”方便HR快速过滤出有效信息,再要“历”用有效信息突出个人的含金量。 2、教育背景少了入学时间~毕业时间,HR判断不出你是否为应届生。 3、如果你的平台账号效果还不错,可以把账号超链接或者用户名贴到对应位置,一是方便HR知道你是具体做了什么内容的运营,看到账号一目了然,二是口说无凭,账号为证,这更有说服力。
面试被问期望薪资时该如何...
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2025-12-17 16:48
今天九点半到公司,我跟往常一样先扫了眼电脑,屁活儿没有。寻思着没事干,就去蹲了个厕所,回来摸出手机刷了会儿。结果老板刚好路过,拍了我一下说上班别玩手机,我吓得赶紧揣兜里。也就过了四十分钟吧,我的直属领导把我叫到小隔间,上来就给我一句:“你玩手机这事儿把老板惹毛了,说白了,你可以重新找工作了,等下&nbsp;HR&nbsp;会来跟你谈。”&nbsp;我当时脑子直接宕机,一句话都没憋出来。后面&nbsp;HR&nbsp;找我谈话,直属领导也在旁边。HR&nbsp;说我这毛病不是一次两次了,属于屡教不改,不光上班玩手机,还用公司电脑看论文、弄学校的事儿。我当时人都傻了,上班摸鱼是不对,可我都是闲得发慌的时候才摸啊!而且玩手机这事儿,从来没人跟我说过后果这么严重,更没人告诉我在公司学个习也算犯错!连一次口头提醒都没有,哪儿来的屡教不改啊?更让我膈应的是,昨天部门刚开了会,说四个实习生里留一个转正,让大家好好表现。结果今天我就因为玩手机被开了。但搞笑的是,开会前直属领导就把我叫去小会议室,明明白白告诉我:“转正这事儿你就别想了,你的学历达不到我们部门要求,当初招你进来也没打算给你这个机会。”合着我没入贵厂的眼是吧?可我都已经被排除在转正名单外了,摸个鱼至于直接把我开了吗?真的太离谱了!
rush$0522:转正名单没进,大概率本来就没打算留你
摸鱼被leader发现了...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务