目录

  • 【算法基础】经典例题说递归
    • 递归简介
      • 递归的适用范围
      • 递归的基本思路
    • 经典例题解析
      • 移梵塔
        • 题目描述
        • 题目分析
        • 题解
      • 九连环
        • 题目描述
        • 题目分析
        • 题解
    • 更新日志

【算法基础】经典例题说递归

递归简介

递归是一种编程技巧,一种解决问题的思维方式。通过函数的自我调用写出简洁漂亮、可解释性强的代码。

递归:参见递归。

递归的适用范围

递归的思维方式适用于解决层层嵌套、层层相似的问题。要解决本层问题就需要先把上一层问题解决掉,而且每一层的解决方法与上一层的解决方法相似。(就像套娃一样,一层套一层,每层都长得差不多)

生活中许多问题都满足层层嵌套的特性。如汉诺塔、九连环的解法,谢尔宾斯基三角形的绘制,二进制数的进位…

拓展阅读:
汉诺塔,二进制和谢尔宾斯基三角形(上)
汉诺塔,二进制和谢尔宾斯基三角形(下)

递归的基本思路

递归最重要的就是找到实现需求的过程中反反复复一直在执行的核心操作是什么,并且找到和核心操作不太一样的边界操作,从而确定触底条件
(这个在触底条件上,和核心操作不太一样的操作,就像套娃里面最小的那个套娃,和别的大套娃不一样,它肚子不开口。边界操作不再自我调用。

层层深入->触底->层层返回

层层深入(核心操作的自我调用,增加递归深度)
触底(不再自我调用,开始返回的分界点)
层层返回(return)

经典例题解析

移梵塔

时间限制: 1 Sec 内存限制: 64 MB

题目描述

有三根柱A、B、C,在A柱上有n块盘片,所有盘片都是大片在下面,小片放在大片上面。并依次编好序号。现要将A上的n块盘片移到C柱上,每次只能移动一片,而且在同一根柱子上必须保持上面的盘片比下面的盘片小,请输出移动方法。

输入
仅一个整数n(n≤20),表示A柱上的盘片数。

输出
输出盘片的移动步骤。

样例输入
3

样例输出
A-1-C
A-2-B
C-1-B
A-3-C
B-1-A
B-2-C
A-1-C

题目分析

读题可知汉诺塔的解法符合层层嵌套、层层相似的特性,故采用递归算法。
任意盘片堆都是由一个更小的小盘片堆加一片大盘片构成的。想要让这个盘片堆移动,就必须三步走:①先把小盘片堆移动到暂存柱上,②这样大盘片才能移动到目标柱,③最后小盘片堆移动到大盘片上。
因为在同一根柱子上必须保持上面的盘片比下面的盘片小,所以移动小盘片堆使小盘片堆离开初始柱的操作可以等价于移动小盘片堆中最大的盘片。
在这里比较特殊的是第一片盘片,它上面没有其他盘片,可以自由移动。

核心操作:把小盘片堆从A柱移动到C柱

边界操作:移动第一片盘片

触底条件:正在移动的盘片是第一片盘片

题解

先放完整代码(C语言)对整体算法有个宏观理解:

#include <stdio.h>void hanoi(int num,char a,char b,char c){if(num==1){printf("%c-%d-%c\n",a,num,c);}else{hanoi(num-1,a,c,b);printf("%c-%d-%c\n",a,num,c);hanoi(num-1,b,a,c);}
}int main()
{int num;scanf("%d",&num);hanoi(num,'A','B','C');return 0;
}

接着是注释版本,可以对照理解:

#include <stdio.h>//hanoi():第num片盘片从起始柱a移动到目标柱c
//b为盘片移动三步走中会用到的暂存柱
void hanoi(int num,char a,char b,char c){if(num==1){//当前移动盘片为第一片盘片的时候直接移动就好啦printf("%c-%d-%c\n",a,num,c);/*↑【注意】↑只有一步所以直接打印了*/}else{//盘片移动三步走hanoi(num-1,a,c,b);//小盘片堆从起始柱移动到暂存柱(a->b)printf("%c-%d-%c\n",a,num,c);//大盘片从起始柱移动到目标柱(a->c)/*↑【注意】↑只有一步所以直接打印了*/hanoi(num-1,b,a,c);//小盘片堆从暂存柱移动到目标柱(b->c)}
}int main()
{int num;scanf("%d",&num);//读入盘片总数numhanoi(num,'A','B','C');return 0;
}

九连环

时间限制: 1 Sec 内存限制: 64 MB

题目描述

九连环是由九个彼此套接的圆环和一根横杆组成,九个环从左到右依次为l~9,每个环有两种状 态:1和0,1表示环在杆上,0表示环不在杆上。初始状态是九个环都在杆上,即:111111111,目标状态是九个环都不在杆上,即:000000000,由初始状态到目标状态的变化规则是:
(1)第一环为无论何时均可自由上下横行;
(2)第二只环只有在第一环为1时,才能自由上下;
(3)想要改变第n(n>2)个环的状态,需要先使第一到第(n-2)环均为下杆,且第n-1个环为上杆,而与第n+l个到第九环状态无关;
(4)每改变一个环,记为一步。
现在九连环由111111111变到000000000,求中间第i步的状态。

输入
仅包含一个整数i。

输出
仅包含中间第i步的状态。如果输入的步数大于实际变换所需的步数,则输出-1。

样例输入
【样例1】
2
【样例2】
500

样例输出
【样例1】
010111111
【样例2】
-1

题目分析

读题可知九连环的解法符合层层嵌套、层层相似的特性,故采用递归算法。

核心操作:解环

想要改变第n(n>2)个环的状态,需要先使第一到第(n-2)环均为下杆,且第n-1个环为上杆,而与第n+l个到第九环状态无关;

边界操作:解第一个环

(1)第一环为无论何时均可自由上下横行;

触底条件:当前在解的环是第一个环

分析解环过程,解环会对前面的环的状态产生影响,但是不会对后面的环产生影响。所以从后往前解环才能把九连环解开。

题解

先放完整代码(C语言)对整体算法有个宏观理解:

#include <stdio.h>int step;
int pos[10]={1,1,1,1,1,1,1,1,1,1};void turn(int num){if(step==0) return;if(pos[num-1]==0) turn(num-1);for(int i=num-2;i>=1;i--){if(pos[i]==1) turn(i);}if(step==0) return;pos[num]=(pos[num]+1)%2;step--;
}int main()
{scanf("%d",&step);for(int i=9;i>=1;i--){turn(i);}if(step==0){for(int i=1;i<=9;i++){printf("%d",pos[i]);}putchar('\n');}else if(step>0){puts("-1");}return 0;
}

然后这里是非常非常详细的注释,看不懂可以对照着看:

#include <stdio.h>//step:操作步数,在turn()函数中倒数计数
int step;//pos数组:记录环的情况
/*【注意】只有九个环但是我开了10个位置
的数组,1~9才是记录环的情况的,其中pos[0]
记录的1是为了减少代码量,避免第一个环的情况
需要单独列出。*/
int pos[10]={1,1,1,1,1,1,1,1,1,1};//turn()函数:改变第num个环的状态,套上或卸下
/*这个函数采用了递归的方法,但是它的触底条件比较隐蔽,
仔细观察可以发现当num=1时函数就不再自我调用了,
它就是边界操作。所以,num=1是触底条件。*/
void turn(int num){/*当步数走完就需要让函数返回,不让它再做其他什么操作使得结果改变*/if(step==0) return;//解环的预先操作,先让当前环前面的环满足解环的条件if(pos[num-1]==0) turn(num-1);/*↑【注意】↑看这里!如果pos数组0~9存状态,当num=0就要单独列出操作了,因为数组会溢出*/for(int i=num-2;i>=1;i--){if(pos[i]==1) turn(i);}/*预先操作过程中最后一步如果step已经到达0,返回到上一层就会一直往下执行,这样step就会变成负数了。这样可不行!赶紧把它return掉!>A<*/if(step==0) return;//解开当前环,并记录步数pos[num]=(pos[num]+1)%2;step--;
}int main()
{//读入题目给出的步数scanf("%d",&step);//从后往前解环for(int i=9;i>=1;i--){turn(i);}//输出答案/*(step==0) 步数走完了(step>0)  步数没走完*/if(step==0){for(int i=1;i<=9;i++){printf("%d",pos[i]);}putchar('\n');}else if(step>0){puts("-1");}return 0;
}

更新日志

2020-2-6
第一版完成!o( ̄▽ ̄)ブ
只写了两题是因为我刷题刷得少orz
递归好难啊好难啊,想破脑壳壳QAQ
但是递归好神奇,本小白对它充满喜欢,我一定要把递归这只小妖精抱紧紧!!!

【算法基础】经典例题说递归相关推荐

  1. 数据结构算法(二)_算法基础之前传(递归、时间复杂度、空间复杂度、二分查找)...

    什么是算法: 间而言之算法(Algorithm):一个计算过程,解决问题的方法 递归的两个特点: 调用自身 结束条件 递归示例: def func(x):if x==0:print("我的小 ...

  2. 算法学习经典例题整理

    陆续会对本篇博客进行更新! 搜索:https://vjudge.net/contest/292597 区间DP:https://vjudge.net/contest/293892 树状背包:https ...

  3. 算法入门经典例题3-2,例题3-3知识点

    3-2打印出输入字母在键盘上的左侧字母值 #include<stdio.h> #include<string.h> int main() {     char a[] = &q ...

  4. LHL算法入门经典 例题3-3最长回文子串

    ##3-3[字符串]最长回文子串 题目描述 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串中连续出现的字符串片段.回文的含义是:正着看和倒着看相同.如abba和yyxyy.在判断回文时, ...

  5. 【C语言|菜鸟教程】100道进阶经典例题详细解答(实例二)

    文章目录 前言 一.题目描述 二.题目分析 三.解题 (1)解题方法一----if-else if语句 1. 思路 2. 程序运行 3. 程序运行结果 (2)解题方法二----if-else if语句 ...

  6. 【C语言|菜鸟教程】100道进阶经典例题详细解答(实例一)

    [C语言|菜鸟教程]100道基础经典例题详解(实例一) 文章目录 前言 一.题目描述 二.题目分析 三.解题 (1)解题方法一 1. 思路 2. 程序运行 3. 程序运行结果 (2)解题方法二 1. ...

  7. C++两个函数可以相互递归吗_[算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进

    [算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进 从学习写代码伊始, 总有个坎不好迈过去, 那就是遇上一些有关递归的东西时, 看着简短的代码, 怎么稀里糊涂就出来了. ...

  8. [算法系列] 深入递归本质+经典例题解析——如何逐步生成, 以此类推,步步为营

    [算法系列] 深入递归本质+经典例题解析--如何逐步生成, 以此类推,步步为营 本文是递归系列的第三篇, 第一篇介绍了递归的形式以及递归设计方法(迭代改递归),;第二篇以递归为引子, 详细介绍了快排和 ...

  9. [算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进

    [算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进 从学习写代码伊始, 总有个坎不好迈过去, 那就是遇上一些有关递归的东西时, 看着简短的代码, 怎么稀里糊涂就出来了. ...

最新文章

  1. Java 基础【04】Swing 组件事件注册
  2. (转)逻辑地址,线性地址,物理地址的差别
  3. 用Tableau画改进版幂函数柱状图
  4. linux查看当前会话文件夹,Linux 记录会话过程的命令
  5. android程序启动动画,Android设置软件启动动画(以及初次安装的几张引导图)
  6. 迁移 WinForm 应用从 dotnet framework 到 dotnetcore3.0
  7. Android studio之导入新库提示Add library ‘Gradle*****@aar‘ to classpath
  8. 字节跳动offer流程多长时间_字节跳动-运营实习生-面经实录(已Offer??)
  9. 2018.9.13,物理仿真实验作业1:测量结果的表示
  10. load Event
  11. python名片管理系统_Python名片管理系统
  12. 数据库 基础学习7— 数据库编程
  13. UBUNTU完美运行TM,RTX,MSOffice,迅雷
  14. java前端商城_网上java商城系统前端开发基础技能浅谈
  15. c语言头文件malloc.h,#includemalloc.h,sys/types.h ,stdlib.h,string.h及C语言头文件
  16. windows 编译n2n
  17. hdu 2036 改革春风吹满地【求多边形面积模板】
  18. 什么是ActiveX控件?
  19. 一、线性回归面试题总结
  20. 分享一款好用的ssh工具

热门文章

  1. 货币市场基金新规正式落地影响多大?
  2. 03、HC-SR04 超声波模块
  3. 计算机网络原理自考真题,自考计算机网络原理真题附标准标准答案.doc
  4. 关于Raspbian中KODI无法播放视频的问题
  5. Python 读取文件时报‘utf-8‘ codec can‘t decode byte 0xfc in position xxxx 的解决方法
  6. windows系统学习总结
  7. java电话正则表达式_java 正则表达式的应用:读取文件,获取其中的电话号码
  8. 如何卸载阿里云ECS服务器的阿里云盾和安骑士
  9. 《念奴娇·断虹霁雨》 黄庭坚
  10. SAC下实现地震波的频率分析、聚束及f-k分析