递归思想

首先说明的一点是递归是一种编程技巧,一种解决问题的思维方式,一些具体的算法都是在这种思维方式上产生的,比如分治算法;递归的基本思想,是把规模较大的一个问题,分解成规模较小的多个子问题去解决,而每一个子问题又可以继续拆分成多个更小的子问题,最重要的一点就是假设子问题已经解决了,现在要基于已经解决的子问题来解决当前问题;或者说,必须先解决子问题,再基于子问题来解决当前问题;在具体实现时候的体现就是调用自身;

递归代码最重要的两个特征:结束条件和自我调用。自我调用是在解决子问题,而结束条件定义了最简子问题的答案;在处理递归问题的时候最重要的就是要明确自己编写的函数的作用是什么,它可以做到什么,然后在这个基础上去分解出子问题,然后递归调用解决子问题。

最基本的一个例题:假如有n阶台阶,你一次可以爬1阶,也可以爬2阶,问爬到第n阶有几种爬法?
我们可以想象一下,当你最后一次爬的时候,你可以从第n-1阶爬一个台阶到第n阶,你也可以从
第n-2阶台阶爬两个台阶到第n阶,因此爬到第n阶的方法等于爬到第n-1阶的方法加上第n-2阶的方
法,这样一分析的话,就相当于要去求两个子问题,并且规模小了一点;
然后我们去编写函数,假设函数为fun(int n),该函数的作用是求爬到第n阶台阶的方法,因此
在函数具体实现的时候,我们可以直接调用它去解决更小规模的子问题,及下面的形式:

int fun(int n)
{
      .....

      return fun(n-1)+fun(n-2);
}

当然函数编写到这里还没有结束,因为如果这样的话就会陷入调用死循环;递归的另一个基本特征是要有结束
条件,因此我们还要在函数中添加结束条件,以避免死循环。结束条件也就是规模最小的时候,我们可以显而
易见的情况,在这里我们可以知道爬到第1阶只有一种爬法,爬到第二节有两种爬法(一阶一阶的爬和一下爬两
阶),因此我们加在函数中即可。

int fun(int n)
{
      if(n==1)
      return 1;
      if(n==2)
      return 2;
      return fun(n-1)+fun(n-2);
}

到这里我们的这个问题就已经解决完了,主要的思想就是递归,但是在很多算法在线测试网站上交上去是不能通过的,
限时超时,这是因为在这个函数具体执行的时候存在很多的重复计算,举个例子,当我们算fun(5)的时候,会去调用
fun(4)和fun(3);在计算fun(4)的时候又会调用fun(3)+fun(2),这里我们就可以看出fun(3)被重复计算了,因此我
们需要将其优化,这就用到了动态规划的思想,在这里先不做讲解,主要介绍的就是递归这样一种思想。

原文地址:https://www.cnblogs.com/noob-l/p/13592071.html