汉诺塔(递归)

递归、搜索与回溯算法



Leetcode汉诺塔

前言

这是记录我学习算法的一个专题,如果你正在备战这类比赛,我想这对你一定有帮助。


一、递归的思想

把一个大型复杂问题层层转化为一个与原问题相似,但规模较小的子问题来求解;直到子问题不能再被拆分,递归就结束了。
简单来说,递归就是将一个问题分解为多个逻辑相同的子问题来解决。

二、汉诺塔

在这里插入图片描述

我简单对上面题目做一下阐述
在这里插入图片描述
有A、B、C三根柱子,其中在A柱子上,按照从大到小的顺序放有N个大小不同的盘子,我们需要做的就是将盘子,从A柱子移到C柱子,在移动时一次只能移动一个,并且要保证小圆盘必须在大圆盘之上。

三、为什么可以使用递归思想?

接下来我,通过举例、画图讲解。

要想保证移动后,大圆盘在小圆盘之下,我们应该想方设法将最大的圆盘移至C,那么该怎么做呢?这时我们就需要利用辅助柱子B了,我们需要将A柱子上的其余盘子移动到B(具体怎么移动,看我们下面讲解),这时A柱子上就剩最大盘子了,我们就可以将最大盘子移至C,这时我们只需要想法将B柱子上的盘子也移动到C就可以完成要求了。
当A柱子上的圆盘个数

N=1时:
在这里插入图片描述
由于只有一个盘子,我们之间移动即可。
N=2时:
在这里插入图片描述
当N=2时,第一步我们要将A顶部盘子,移动到B柱子,这时就可以直接将A底部盘子移动到C柱子,再将B柱子上的盘子移动到C柱子程序结束。
N=3时:
在这里插入图片描述
我们仍需要的是将,最大的盘子移动至C柱子,也就是说,我们需要将A柱子上,上面两个盘子移动到B柱子,该怎么完成它呢?大家仔细想将两个盘子,移动到一个柱子上!!!这不就是N=2的情况吗?无非就是目标柱子从C变为了B,我再啰嗦一点,将这里画出来
在这里插入图片描述
到这里A柱子上的两个盘子算都移动到B柱子上了,接下来只需要将最后一个移动到C柱子即可。

大家都知道怎么移动的了,接下来我就将上面的看为一个整体

在这里插入图片描述
N=4时:
在这里插入图片描述
我们需要将最大的移动到C,就需要将上面三个移动到B,这不又是我们讲过的一个吗?接下来就不赘述了
在这里插入图片描述
从N=2开始,N每增加一个数都可以被我们看成,在前一个基础上,多一点了个最大盘子,这就叫做将一个问题分解为逻辑相同的子问题。
分析上面情况我们可以看到,当N=1是执行步骤不同,递归条件这不就来了

四、代码实现

再看代码时,注意看注释!!!!

这里是oj题,要在网站上跑!!

 void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        dfs(A,B,C,A.size());//将A上的A.size()个圆盘移动到C柱子
    }
    void dfs(vector<int>& a, vector<int>& b, vector<int>& c,int n)
    {
        if(n==1)//柱子上圆盘为1,直接移动并返回至上一层
        {
            c.push_back(a.back());
            a.pop_back();
            return ;
        }

        dfs(a,c,b,n-1);//将使用C作为辅助柱子,将A柱子的前n-1个移动到B柱子
        c.push_back(a.back());//此时A柱子上只剩一个最大盘子,直接移动至C柱即可
        a.pop_back();
        dfs(b,a,c,n-1);//这时最大圆盘在C上,在将B柱子上剩余n-1个圆盘移动到C柱子即可
        return;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值