这两个递归算法的实现有什么区别?

时间:2016-06-26 20:07:45

标签: recursion

我正在做一个leetcode问题。

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

所以我首先尝试了这个实现并获得了“超过运行时间”(我忘了确切的术语,但这意味着实现很慢)。所以我更改了版本2,它使用数组来保存结果。老实说,我不知道递归是如何在内部工作的,以及为什么这两种实现具有不同的效率。

版本1(慢):

class Solution {
   // int res[101][101]={{0}};
public:
    int uniquePaths(int m, int n) {
        if (m==1 || n==1) return 1;
        else{ 
            return uniquePaths(m-1,n) + uniquePaths(m,n-1);
        }
    }
};

版本2(更快):

class Solution {
    int res[101][101]={{0}};
public:
    int uniquePaths(int m, int n) {
        if (m==1 || n==1) return 1;
        else{ 
            if (res[m-1][n]==0) res[m-1][n] = uniquePaths(m-1,n);
            if (res[m][n-1]==0) res[m][n-1] = uniquePaths(m,n-1);
            return res[m-1][n] + res[m][n-1];
        }
    }
};

1 个答案:

答案 0 :(得分:1)

版本1速度较慢,因为您一次又一次地计算相同的数据。我会尝试在不同的问题上解释这个,但我想你知道斐波那契数字。您可以通过遵循递归算法来计算任何斐波纳契数:

fib(n):
if n == 0 then return 0
if n == 1 then return 1
return fib(n-1) + fib(n-1)

但实际上你在计算什么?如果你想找到fib(5),你需要计算fib(4)和fib(3),然后计算fib(4)你需要再次计算fib(3)!看一下图像就可以完全理解了: Fibonacci recursion tree

您的代码中也存在相同的情况。即使您之前计算过,也可以计算uniquePaths(m,n)。为避免这种情况,在第二个版本中,您使用数组存储计算数据,而在res[m][n]!=0

时,您不必再次计算数据