3、基本解题步骤或方法:
1) 明确递归函数功能。一定要明确递归程序的功能,对递归程序要完成的功能模棱两可、一知半解,往往导致逻辑混乱,写不出正确的递归程序。
2) 找出递归终止条件。所谓递归,就是在函数内部代码调用函数本身,所以,我们必须要找出递归的结束条件,否则,就会一直调用自己,陷入死循环。也就是说,我们需要找出当参数为何值时,递归结束。请注意,这个时候我们必须能根据参数的值,直接知道函数的结果是什么。
3) 找出递归等价关系。即找出怎么通过递归把一个大问题分割成若干小问题,通过解决若干个小问题再组合起来,来求解这个大问题。
4) 审视已写好的递归程序,看看递归终止条件是否足够严谨,防止不严谨的递归终止条件导致程序陷入死循环。
4、例题解析:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
l、明确递归函数功能
假设函数Solution的功能是求青蛙跳上一个n级的台阶有多少种方法。先定义出函数的框架,如下:
// 求青蛙跳上一个n级的台阶,总共有多少种跳法
int Solution(int n)
{
}
找出递归终止条件
找出递归终止条件,最常用的手法就是压缩问题的规模到很小的程度,小到可以直接算出Solution的返回值。所以,当n = 1时,有:
// 求青蛙跳上一个n级的台阶,总共有多少种跳法
int Solution(int n)
{
if (n == 1) {
return 1;
}
}
l 找出递归等价关系
这是求解递归问题的难点,需要结合具体的问题认真分析。就本例而言,青蛙一次可以跳一个或者两个台阶,根据青蛙第一次跳一个还是两个台阶, 有两种情况:
1) 第一次跳一个台阶:因为第一次跳了一个台阶,那么子问题变为剩下的n – 1级台阶的跳法,有Solution(n – 1)种。
2) 第一次跳两个台阶:因为第二次跳了一个台阶,那么子问题变为剩下的n – 2级台阶的跳法,有Solution(n – 2)种。
所以,青蛙跳上n级台阶的跳法,就是这两种情况下的跳法之和,即Solution(n) = Solution(n – 1) + Solution(n – 2)。至此,等价关系就找出来了,代码如下:
// 求青蛙跳上一个n级的台阶,总共有多少种跳法
int Solution(int n)
{
if (n == 1) {
return 1;
}
return Solution(n - 1) + Solution(n - 2);
}
l 审视递归终止条件是否严谨。
上面的程序,当n = 2时,会有Solution(2) = Solution(1) + Solution(0)。然后求Solution(0)的时候,会调用Solution(0) = Solution(-1) + Solution(-2),从而导致无限调用,进入死循环。另外,当n = 2时,通过Solution(1) + Solution(0)求Solution(2),会求得Solution(2) = 1,也是不正确的,进一步分析下来,Solution(n) = Solution(n - 1) + Solution(n - 2),只在n > 2时才成立。
进一步完善递归终止条件,代码如下:
// 求青蛙跳上一个n级的台阶,总共有多少种跳法
int Solution(int n)
{
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
return Solution(n - 1) + Solution(n - 2);
}
对终止条件进行合并优化,最终代码如下:
// 求青蛙跳上一个n级的台阶,总共有多少种跳法
int Solution(int n)
{
if (n <= 2) {
return n;
}
return Solution(n - 1) + Solution(n - 2);
}