递归、搜索与回溯算法
文章目录
- 递归、搜索与回溯算法
- 前言
- 一、递归的思想
- 二、汉诺塔
- 三、为什么可以使用递归思想?
- 四、代码实现
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;}